3D地图和场景管理
其他项目的做法
- 方案
- 将场景用八叉树划分,最多三层
- 物体根据坐标直接加入八叉树的叶节点(忽略了体积和包围盒)
- 移动采用完全相信客户端的做法
- 通过MoveState来记录移动过程,客户端上传开始位置、结束位置、持续时间信息,服务器根据开始位置和结束位置、以及时间计算出速度。
- 只有在其他对象主动查询或者RegionSwitch的OnTimer时候,才会做移动,八叉树节点切换
- 如果没有主动查询,中间过程是没有体现的
- 疑问
- 如果出现网络延迟,客户端中途改变移动方向或者目的地点时,两端的位置会有严重偏差,这时如何同步?
- 如果地面上有陷阱,在起点和终点之间,是否会被触发?
- 忽略了体积的情况下,如何做碰撞检测?
TrinityCore的做法
TO-DO
我的想法
- 场景用八叉树管理,在八叉树中只保存动态物体,如玩家角色、NPC、怪物、子弹等,姑且称为动态检测。八叉树可以用来做广播和碰撞检测,查找效率会高不少。八叉树的一个叶节点的大小可以设计为边长为一屏的立方体
- 地图和人物移动完全根据导航网格来校验
- 碰撞检测可以通过导航网格+动态检测的方式来判断,和场景以及静物的碰撞,可以通过导航网格来检测,和动态物体的碰撞,通过动态检测来判断
- 人物移动可以采用MoveList的方式,但是和其他项目不同的是,我们可以假设每次移动总是固定的距离(如半屏),客户端发来的应该是TimeStamp,StartPos,direction,velocity,EndPos。服务端根据StartPos,direction,velocity来计算EndPos,如果StartPos和人物的当前位置偏差,以及服务器算出的EndPos和客户端的EndPos偏差在允许范围内,并且移动速度<=当前允许最大移动速度,则认为客户端的行为是合法的,采信客户端的移动方式,更新人物的当前位置并广播移动消息。
实现
- 八叉树:假设场景的边界是一个立方体(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游服注意事项
- 一个账号可建多个角色
- 角色, 物品, 幻兽, 军团id用64位,可将服务器id和角色id整合成一个唯一的id下发到客户端,为了将来方便做跨服,转服
- 已经在登录过程中再被登录,后者可直接登上,前者自动被踢下线
- 断线5分钟内自动快速重连,包括网络环境切换的时候的自动重连尽量不让玩家感觉到,比如从wifi到4G的自动切换游戏中目前是会掉线的
- 可做到角色在账号间的转移(同一个服务器下)
- 可做到自己账号下的角色的自助移服(重名让玩家自己修改)