A星寻路和nevmesh寻路的一些技巧
A星寻路和nevmesh寻路是网游里最常用的两种寻路方式了,实现代码可以百度,今天跟大家分享下,在不同情况下,A星寻路和nevmesh寻路的一些技巧。
一:客户端nevmesh 和 服务端A*算法的转换
比如做一个网游时,客户端使用nevmesh寻路,而服务端因为某些原因习惯使用A*算法,可以使用如下方式转换:
[mw_shl_code=applescript,true]public void Sync()
{
//判断是否处于寻路//
if (LocusPoints.Count < 2)
{
return;
}
//获取下一个路径点//
Vector3 nextPosition = LocusPoints[0];
Vector3 nextPosition2 = LocusPoints[1];
//如果两者大于一个格子,则插点//
if (Vector3.Distance(nextPosition ,nextPosition2) > 0.5f)
{
// * 方向//
Vector3 directionVector3 = nextPosition2 - nextPosition;
//预测下一个路径点//
Vector3 targetVector3 = directionVector3.normalized * 0.5f + nextPosition;
if (targetVector3.x == 0 && targetVector3.z == 0)
LocusPoints.Insert(1, targetVector3);
}
//TODo:和服务端同步一次位置//
//记录上一个出发点,用于平滑路径
NewLocusPointRotation = SelectedLightProjector.transform.rotation;
NewLocusPointPosition = SelectedLightProjector.transform.position;
NewLocusPointStartTime = Time.fixedTime;
mFollowWayPointsState.begin = true;
}[/mw_shl_code]
上面这段代码,实际上就是每隔一定距离,就对Nevmesh的路径点进行插点,然后转换为A星的格子位置。
这样服务端的小伙伴就可以验证客户端的寻路的真伪了。
二: A*算法的障碍碰撞
一般的A*算法代码是把所有障碍当做一个格子。但某些时候有的物体大,有的物体小,碰撞范围大小不一,那么需要动态传递参数
[mw_shl_code=applescript,true] public bool CanReach(int x, int y)
{
///加入自身碰撞器后,需要判断该点周围 全无阻挡///
for (int i=-selfBlock; i<=selfBlock; i++)
{
for(int j=-selfBlock; j<=selfBlock; j++)
{
if(MazeArray[x+i, y+j]<=0)
return false;
}
}
return true;
}[/mw_shl_code]
三:客户端nevmesh 和 A*算法的混用
因为项目的某些需求,使用单一的寻路方式,性能或者效果可能不好,那么可以混用几种寻路方式。
提供两种思路:
1.使用nevmesh检测静态障碍,在这段代码内部,再使用A*专门检测动态障碍,调整nevmesh的路径。
2. 因为一些特殊需求,比如寻找NPC,使用nevmesh检测长范围的寻路,在路径的最后一段,使用A*检测小范围的障碍。
浙公网安备 33010602011771号