3D地图和场景管理

游戏开发 Apr 2, 2023

其他项目的做法

  • 方案
    1. 将场景用八叉树划分,最多三层
    2. 物体根据坐标直接加入八叉树的叶节点(忽略了体积和包围盒)
    3. 移动采用完全相信客户端的做法
    4. 通过MoveState来记录移动过程,客户端上传开始位置、结束位置、持续时间信息,服务器根据开始位置和结束位置、以及时间计算出速度。
    5. 只有在其他对象主动查询或者RegionSwitch的OnTimer时候,才会做移动,八叉树节点切换
    6. 如果没有主动查询,中间过程是没有体现的
  • 疑问
    1. 如果出现网络延迟,客户端中途改变移动方向或者目的地点时,两端的位置会有严重偏差,这时如何同步?
    2. 如果地面上有陷阱,在起点和终点之间,是否会被触发?
    3. 忽略了体积的情况下,如何做碰撞检测?

TrinityCore的做法

TO-DO

我的想法

  1. 场景用八叉树管理,在八叉树中只保存动态物体,如玩家角色、NPC、怪物、子弹等,姑且称为动态检测。八叉树可以用来做广播和碰撞检测,查找效率会高不少。八叉树的一个叶节点的大小可以设计为边长为一屏的立方体
  2. 地图和人物移动完全根据导航网格来校验
  3. 碰撞检测可以通过导航网格+动态检测的方式来判断,和场景以及静物的碰撞,可以通过导航网格来检测,和动态物体的碰撞,通过动态检测来判断
  4. 人物移动可以采用MoveList的方式,但是和其他项目不同的是,我们可以假设每次移动总是固定的距离(如半屏),客户端发来的应该是TimeStamp,StartPos,direction,velocity,EndPos。服务端根据StartPos,direction,velocity来计算EndPos,如果StartPos和人物的当前位置偏差,以及服务器算出的EndPos和客户端的EndPos偏差在允许范围内,并且移动速度<=当前允许最大移动速度,则认为客户端的行为是合法的,采信客户端的移动方式,更新人物的当前位置并广播移动消息。

实现

  1. 八叉树:假设场景的边界是一个立方体(BoxMin, BoxMax)。立方体的中心为BoxCenter
    • Children[0, 0, 0]=(BoxMin.x, BoxCenter.y, BoxMin.z), (BoxCenter.x, BoxMax.y, BoxCenter.z)
    • Children[1, 0, 0]=(BoxCenter.x, BoxCenter.y, BoxMin.z), (BoxMax.x, BoxMax.y, BoxCenter.z)
    • Children[0, 1, 0]=(BoxMin),(BoxCenter)
    • Children[0, 0, 1]=(BoxMin.x, BoxCenter.y, BoxCenter.z), (BoxCenter.x, BoxMax.y, BoxMax.z)
    • Children[0, 1, 1]=(BoxMin.x, BoxMin.y, BoxCenter.z), (BoxCenter.x, BoxCenter.y, BoxMax.z)
    • Children[1, 0, 1]=(BoxCenter), (BoxMax)
    • Children[1, 1, 0]=(BoxCenter.x, BoxMin.y, BoxMin.z), (BoxMax.x, BoxCenter.y, BoxCenter.z)
    • Children[1, 1, 1]=(BoxCenter.x, BoxMin.y, BoxCenter.z), (BoxMax.x, BoxCenter.y, BoxMax.z)

UE4游服注意事项

  1. 一个账号可建多个角色
  2. 角色, 物品, 幻兽, 军团id用64位,可将服务器id和角色id整合成一个唯一的id下发到客户端,为了将来方便做跨服,转服
  3. 已经在登录过程中再被登录,后者可直接登上,前者自动被踢下线
  4. 断线5分钟内自动快速重连,包括网络环境切换的时候的自动重连尽量不让玩家感觉到,比如从wifi到4G的自动切换游戏中目前是会掉线的
  5. 可做到角色在账号间的转移(同一个服务器下)
  6. 可做到自己账号下的角色的自助移服(重名让玩家自己修改)

标签