在MMORPG中,其他玩家和怪物的同步做法

在MMORPG中,其他玩家和怪物的同步做法

1)在MMORPG中,其他玩家和怪物的同步做法
​2)AssetBundle通过Offset加密/解密问题
3)加载预制体API区别
4)关于MaterialPropertyBlock的使用问题


这是第340篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。

UWA社区主页:community.uwa4d.com
UWA QQ群:465082844

Network

Q:关于在MMORPG中,其他玩家和怪物的同步做法:

目前的做法是怪物和玩家都有一个状态机,状态的改变是根据服务器下发的状态进行状态设置的,但是目前有个问题就是如果出现本地卡顿或者网络波动等其他原因导致客户端之前的动作还没有结束,服务器又下发了新的状态,这个时候如果直接设置新状态就会表现异常也会出现位置不同步的情况(例如客户端还没有移动结束,由于卡顿或者延迟原因又收到了攻击状态,如果这个时候直接攻击就表现出又移动又攻击的情况)。

因为之前没有这方面的经验,在网上查了其他人的做法,说是要做对其他角色的状态预测,如果出现同步异常,用插值让异常的对象迅速恢复到正常的状态。

那么:
1. 其他玩家和同步是用状态机加预测去做的吗?
2. 怪物同步的一般做法大概是怎么样的?和其他玩家类似吗?
3. 在做同步的时候有哪些要注意的点呢?

A:

  1. 其他玩家和怪物的同步一般会采用状态同步和状态预测相结合的方式。状态同步是指服务器将所有角色的状态同步给客户端,客户端根据这些状态来更新角色的状态机。状态预测是指客户端根据自己的状态机来预测其他角色的状态,并根据这些预测结果来更新自己的视图。预测的结果需要通过与服务器的同步来验证,如果预测的结果和服务器的结果不一致,就需要进行状态修正。

  2. 怪物的同步和其他玩家的同步类似,都需要采用状态同步和状态预测相结合的方式。不同的是,怪物通常由服务器控制,因此服务器可以更精确地控制怪物的状态和行为,这样可以减少客户端的预测量和同步量,从而提高同步的效率。

  3. 在做同步的时候,需要注意以下几个点:

  • 状态同步的频率要足够高,确保角色的状态能够及时同步到客户端,减少状态预测的误差。
  • 状态预测要尽量准确,采用合适的算法和参数来提高预测的准确率。
  • 当客户端出现卡顿或者延迟时,需要采用插值和修正等方式来让角色迅速恢复到正常的状态,避免出现位置不同步的情况。
  • 需要对角色的移动和攻击等行为进行校验,避免作弊和外挂的出现。
  • 对于客户端和服务器之间的通信,需要采用可靠的协议和加密方式来保证通信的安全和稳定。

感谢NG週@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/64200a526778221ae306a89d


AssetBundle

Q:打包AssetBundle想用偏移量简单做一下加密:

App版本使用:
AssetBundle.LoadFromFile(filePath, 0, offset)

但是WebGL版本使用:
UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(urlPath);
AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);

未找到相关接口,请问大家有没有什么思路?

A:在WebGL平台上使用UnityWebRequest发送网络请求获取AssetBundle文件,获取到后在内存中进行解密,然后将解密后的AssetBundle内容存储到内存中。

在内存中加载AssetBundle,可以使用AssetBundle.LoadFromMemoryAsync(byte[] buffer)方法或者AssetBundle.LoadFromMemory(byte[] buffer)方法。

感谢NG週@UWA问答社区提供了回答,欢迎大家转至社区交流:
https://answer.uwa4d.com/question/645ca9ccb068ba13373fb572


Loading

Q:请问PrefabUtility.LoadPrefabContents和AssetDatabase.LoadAssetAtPath这两个加载预制体的API具体有什么区别呢?

都试过测试感觉差不多,速度上没多大区别:
PrefabUtility.LoadPrefabContents之后需要PrefabUtility.SavaAsPrefabAsset保存和PrefabUtility.UnloadPrefabContents释放;AssetDatabase.LoadAssetAtPath之后,使用EditorUtility.SetDirty标记,然后AssetDatabase.SaveAssets保存。

针对以上问题,有经验的朋友欢迎转至社区交流分享:
https://answer.uwa4d.com/question/648047ab47691b75be04aa96


Rendering

Q:3D麻将项目,一个牌面一个材质球。我使用了一个不带材质球的麻将预制体,然后在创建麻将牌的时候实例化预制体,根据牌面值查找并赋值对应材质球, GetComponent().shareMaterial = XXXXX。

材质球使用的Shader是URP里的Complex Lit。

有个需求是点击手中麻将牌时,修改已经打出的牌(相同牌面的)在桌面的牌的颜色,但不能影响手中的牌的颜色。于是我用MaterialPropertyBlock的SetPropertyBlock方法修改已打出的牌的颜色值,但是不生效。

已打出牌的材质球的Inspector下方有提示“MaterialPropertyBlock is used to Modify these values”。网上也有一些解答,但还是没搞懂。请问正确流程和做法应该怎样才行呢?

针对以上问题,有经验的朋友欢迎转至社区交流分享:
https://answer.uwa4d.com/question/647e96efe63c097f73e2f2d9

封面图来源于网络


今天的分享就到这里。生有涯而知无涯,在漫漫的开发周期中,我们遇到的问题只是冰山一角,UWA社区愿伴你同行,一起探索分享。欢迎更多的开发者加入UWA社区。

UWA官网:www.uwa4d.com
UWA社区:community.uwa4d.com
UWA学堂:edu.uwa4d.com
官方技术QQ群:465082844