Unity进阶教程AOI算法原理详解

最新课程《全栈双客户端(Unity/Cocos) TurnKey方案》更新了AOI专题,今天分享一下AOI算法的实现原理。

AOI的功能和作用

在MMORPG网路游戏当中,单服同时在线一般都会有几千人。当有个玩家执行一个操作,理想情况下要把玩家的操作广播同步给单服全部的几千人。同时别人的操作,也要发给这个玩家,这样就会导致服务端数据通讯的量非常的大。导致客户端也需要创建几千个"节点"来接收这些数据。

如何优化?其实我们发现,虽然一个游戏地图同时在线的人数可能有几千人,但是我们每次能看到的也就是几十人而已(国战等特殊情况除外)。我们只要接收"""周围人"的状态变化和呈现动画即可。"周围"对应一个范围区域,这个范围区域我们把它叫做AOI(Area Of interested)感兴趣区域。

做MMORPG游戏的时候,我们在服务端规定一个范围为AOI的大小。通常为玩家的视野范围,在玩家A 感兴趣AOI范围内的角色,服务端都会把这些角色状态与操作同步给玩家A对应的客户端,不在范围内的,不同步。这样服务端同步给每个客户端的数据量就大大减少,而客户端要创建的接收数据的玩家只有几十个对象。AOI的核心算法就是要在服务端对所有的玩家做好管理,当服务端上某个玩家A有消息的时候,服务端要快速的找到玩家A"周围"的人,然后把消息同步给它们,这就是AOI算法的核心。

AOI 核心算法详解

AOI主流的核心算法目前有九宫格与十字链表两种。

基于九宫格的AOI 算法核心:

Step1: 根据地图,结合屏幕上玩家游戏视野,先确定"可视范围"大小,作为AOI的范围。

Step2: 视野大小确定后,玩家A感兴趣的区域是以它为中心,固定的视野大小为范围,将视野范围分成"九宫格"来作为玩家A周围的AOI区域,如下图的9个红色的框,包围蓝色的玩家;

Step3: 把视野大小 / 3 就可以得到每个格子的大小,这样就可以把地图平面分成MxN个格子。

Step4: 针对每个格子,设计数据结构,保存当前格子中的"物品","角色", "NPC"等。

Step5: 当玩家A有操作的时候,根据玩家A的坐标 / 每个块的大小,就可以得到玩家所在块的坐标, 就能快速的找到玩家所在的块,进一步能锁定玩家周围的9个块。这样,遍历这9个块里面的玩家,把玩家A的状态同步出去,对于其它玩家也类似。

Step6: 由于玩家,NPC,怪物的移动,会导致它由一个格子,到另外一个格子,我们称此为发生了"格子变化"。们做如下处理:

  1. :找到原来玩家A所在的旧的九宫格区域,得到"旧九宫格"格子,现在玩家A所在的新的九宫格区域,得到"新九宫格"格子。
  2. : 对比玩家A前后两个九宫格,即在旧的九宫格又在新的九宫格的格子,不用做任何处理,针对在旧九宫格但不在新九宫格里的格子,发消息给玩家A的客户端,让客户端把这些角色从客户端地图上删除掉。在新九宫格但不在旧九宫格的格子,要发送消息给玩家A客户端,让他们把新进来的玩家创建出来。
  3. 针对在旧九宫格但不在新九宫格里的格子,给这些格子里玩家对应的客户端发消息,玩家A离开了它们的视野,删除玩家A。针对在新九宫格不在九九宫格的格子,给这些格子里的玩家对应的客户端发送消息,玩家A进入到它们的视野,把玩家A创建出来。

移动的玩家突然闯入AOI视野

有时候,我们会遇到一个移动中的角色,移动的过程中,突然传入玩家A的视野, 但是玩家A的客户端不知道这个角色要走向何方,所以不知道如何处理,对于这种突然闯入视野的情况,我们移动,会重新发送一个移动事件,让玩家A的客户端能补齐对应的移动。对于攻击与死亡,也类似。

End

上一波《全栈+双客户端(Unity/Cocos)AOI的专题》的效果,

相关推荐
金銀銅鐵6 小时前
带您看懂字节码指令(二):空循环里有什么
java·后端·ai编程
吴名氏.7 小时前
Java转AI Agent教程(第十三周)混合检索与重排
java·数据库·人工智能·ai·ai agent
.痞老板.8 小时前
java ee--多线程(进阶)
java·java-ee
深入云栈10 小时前
Netty 4.2.x 源码深度解析 (二十三):ByteBuf 核心设计 —— 索引、类型与零拷贝
java·后端·架构
wang_shu_mo_ran11 小时前
MyBatis 从入门到进阶(一)
java·spring·mybatis
寂寞的船11 小时前
【Unity Bug挑战】第12期 Awaitable 二次 await 死锁之谜 —— 为什么同一个异步操作等两次就卡死?
unity·c#·游戏引擎·bug
量化分析码农12 小时前
股票历史数据的复权参数对照:多级别返回的字段与数值差异
java·javascript·后端
猫猫不是喵喵.12 小时前
从0到1创建一个微服务项目
java·数据库·微服务·1024程序员节
瑞雪兆丰年兮12 小时前
JavaWeb-day13-SpringBootWeb事务管理&AOP
java·开发语言·springboot·javaweb·事务·web·aop
曲径海盗12 小时前
Try-Except怎么用,3个追问解答在自动化下的应用
java·jvm·oracle