Home

Awesome

DecimalNavigation

基于定点数的寻路解决方案(实际使用的是 long 类型), 适用于 unity 帧同步框架。

注意:寻路因为计算过程中的“离散”程度较高,输出的结果来自预先存储的浮点数,因此发生不同步的概率较小。当项目重度依赖寻路的情况下应使用此库。

TO DO List

基准测试效率比 Unity 自带算法快大约 30%~800%!

为什么有用

在帧同步框架中,逻辑交由客户端自行判断,因此逻辑判断必须高度一致。

浮点数因以下原因无法保证多端同步:

而寻路是游戏中举足轻重的模块,市面上的主流寻路大多是 float 运算。

因此 DecimalNavigation 在运算层面选择了 long。

工作机制

开发时

DecimalNavigation 把 Unity 生成的 NavMesh 网格规格化另存。 数据加工流程:

btw,存储的精度是可配置的,默认为 100(100 分 1m)。

运行时

初始化流程:

寻路流程:

快速入门

0.导入 DecimalNavigation

拷贝 Assets 下内容到自己的 Assets 下。

如果成功导入,菜单会出现Tools/生成标准化寻路网格

1.得到网格

2.网格精度修改*

如果想要自己指定网格存储精度,可按如下步骤操作:

3.开始寻路

引用命名空间

using DecimalNavigation;

初始化时,新建一个寻路实例

//在Inspector中指定上一步得到的成果
public NormalizedNavmeshAsset navMesh;

private NavigationSystem system;

void Start(){
  system = new NavigationSystem(navMesh);
}

点击地面,得到路线

List<Point3D> path;

private void Update()
{
    if (Input.GetMouseButton(0))
    {
        var ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hit;
        if (Physics.Raycast(ray, out hit))
        {
            var p = hit.point;
            path = system.CalculatePath(
                new Point3D(transform.position * navMesh.precision),
                new Point3D(p * navMesh.precision)
            );
        }
    }
}

绘制路径折线,便于观察


private void OnDrawGizmos()
{
    if (null == path) return;
    Gizmos.color = Color.blue;
    for (int i = 1; i < path.Count; i++)
    {
        Gizmos.DrawLine(
            path[i - 1].toVector3() / navMesh.precision,
            path[i].toVector3() / navMesh.precision
        );
    }
}

写在最后

这个框架我会随着工作不断完善,不断优化。感谢期待,也感谢好的建议。