Unity 分批加载玩家形象
需求背景
游戏房间上限最大可以有count个人,当用户进入房间后,需要去远程服务器获取这count个人物的服装配置, 获取成功以后进行逐个加载。
目前的方案是一次性获取所有人物的配置,然后以一种几乎同时加载的方式去做。
这种方案最坏的情况下会同时有count个换装的任务在运行,导致count个任务之间抢占CPU,结果就是看起来卡顿。
为了使游戏的表现更加流畅,需要设计一种方案进行有优先级的批量加载。
预期效果
- 无论何时,用户自己的形象配置获取成功以后,立即优先加载。
- 其他用户形象返回后进入队列,进行分批加载。
- 其他用户优先加载可视区域内部的形象。
- 如果都处于可视区域内部,那么优先加载距离摄像机近的形象。
- 拥有动态调整能力,初始可以同时加载n个形象,如果检测到平均加载时间过长,动态降低并发任务上限,最低不少于m,如果平均时间在可接受范围,尝试增加并发数。
实现方案
用户自身的形象加载不受优先级控制,获取后立即加载。
优先级队列
分析完需求和预期效果之后,我们可以很容易地想到优先级队列这个数据结构。
优先级队列虽然是叫做队列,但是实现起来可以使用各种数据结构,我们可以采用堆,栈,队列。
对于我们的场景来说,我们高频使用的操作除了push和pop之外,最常用的应该就是一次性取出前n个,从这角度考虑,我们应该采用队列的方式去实现。
正好C#虽然没有默认实现的优先级队列,但是有个SortedList可以使用。
优先级算法
上面算法最重要的一点就是计算优先级。
基于我们的几点考虑:
- 可视区域内部优先级一定高于不可视区域。
- 人物之间的距离不会超过1000.
我们可以使用int类型作为Priority,计算人物和摄像机之间的距离,然后用1000减去该距离作为初始优先级,接下来判断如果是处于可是区域内部,优先级再加上1000,否则加上0;
计算两点之间的距离很简单,那么问题就是如何判断一个物体是否处于可视区域内。
如何判断是否处于可视区域
https://blog.csdn.net/cyf649669121/article/details/110580986
由于我们就是要判断先渲染那个形象,所以只能用坐标判断
1 | public bool IsVisableInCamera |