Unity Navigation Mesh 自动寻路

  • Post author:
  • Post category:其他


Unity Navigation Mesh 自动寻路

利用Unity自带的导航网格寻路,Unity2022.1.2f1c1

(1)创建地形

在这里插入图片描述

利用最基础的 Cube 模型搭建的一个简单的场景

在 Hierarchy 面板下

(1.1)可走的路:可以正常行走、通行的地方:如 地面、台阶、斜坡、平台 等

Road 下面的物体是搭建的可走的路,包括地面、左下方的台阶、左上方一个悬空的台,右上方一个带斜坡的台

(1.2)障碍物:不能走、不能通过的地方:如墙、门、较大的物体

Obstacle 下面的红色墙

障碍物需要添加组件:NavMeshObstacle、Rigidbody

NavMeshObstacle 勾选 Carve

(1.3)连接点:从一个点可以走、跳跃 到达另一个点,如图中 上方两个平台都是悬空的,且两个平台之间有一定的距离,如果想让人从一个台阶上跳跃到另一个台阶上,可以分别在两个平台上建立两个连接点。

Line 下面的连接点, start 和 to 是一组,from 和 end 是一组

在一个物体上添加组件:OffMeshLink

将需要连接的两个点分别拖拽到 OffMeshLink 组件的 Start、End 上

在这里插入图片描述

(2) 设置面板

菜单栏:Window->AI-Navigation 打开设置面板

在这里插入图片描述

(2.1) Agents 设置

在这里插入图片描述

Radius:人的半径

Height:人的高度

Step Height: 人一步漫出的高度,上台阶的高度

Max Slope:人可以行走的斜坡的最大角度

(2.2) Object 设置

在这里插入图片描述

全选:路、连接点、障碍物

显示已选择了 13 个物体

勾选 Navigation Static

Generate OffMeshLinks 自动生成连接点,此处先不勾选,后边再说

设置完成然后到 Bake

(2.3) Bake 设置

在这里插入图片描述

各种参数想了解的自己查文档就行了

点击

Bake 按钮

查看烘焙结果

在 Scene 视图下看到的效果如下图( 可以跟上边第一张烘焙之前的图对比下)

场景被划分成了很多凸多边形的连接

蓝色部分就是可行走的路

白色部分是不可行走的地方

还有四个圈,两两之间有一个双向箭头连接着,这就是两组连接点,人可以从一个连接点跳跃到另一个连接点

在这里插入图片描述

(2.4)导航网格烘焙后不想要了如何撤销?

在 Back 面板点击 下方的

Clear 按钮

即可清除烘焙好的导航网页

(3)Object -> Generate OffMeshLinks 回到 Object 设置面板

全选:路、连接点、障碍物

勾选 Navigation Static

勾选 Generate OffMeshLinks

在这里插入图片描述

(3.1) 到 Bake 面板

设置 Generated Off Mesh Links

Drop Height:人在两个连接点之间 上下跳的最大高度 单位米

Jump Distance:人在两个连接点之间 跳跃的最大距离 单位米

在这里插入图片描述

点击

Bake 按钮

,看效果

多了很多组连接点,这是烘焙路径时根据台阶、平台、路面之间的高度以及距离自动生成了很多连接点

在这里插入图片描述

(4) 因为自动生成的连接点很多不是我们想要的,我们想自己控制在哪里添加连接点,所以我们不用自动生成的连接点,将烘焙好的导航网格

Clear

掉,删除掉 Generated Off Mesh Links 设置,重新

Back

(5)导航网格生成好了,如何使用?

创建一个圆柱体Cylinder就是我们的角色了

添加组件:NavMeshAgent

各种参数可查文档

在这里插入图片描述

添加移动控制脚本 MoveController.cs 添加到 角色圆柱体Cylinder 上

引用命名空间

using UnityEngine.AI;

using UnityEngine;
using UnityEngine.AI;

public class MoveController : MonoBehaviour
{
    private NavMeshAgent _navMeshAgent;
    GameObject go;

    void Start()
    {
        _navMeshAgent = GetComponent<NavMeshAgent>();
        _navMeshAgent.speed = 3.5f;

        go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        go.transform.localScale = Vector3.one * 0.3f;
        go.GetComponent<MeshRenderer>().material.color = Color.red;
    }

    void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            FindPoint();
        }
    }

    private void FindPoint()
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        RaycastHit hitInfo;

        //发射射线,如果射线碰撞到带有 Collider 组件的对象将返回 true,否则返回 false
        if (Physics.Raycast(ray, out hitInfo))
        {
            // hitInfo.point 为射线和球面碰撞点坐标(鼠标点击球面坐标)
            SetDestination(hitInfo.point);
            go.transform.position = hitInfo.point;
        }
    }

    private void SetDestination(Vector3 destination)
    {
        _navMeshAgent.destination = destination;
    }
}

运行Unity 通过鼠标点击,获取到一个位置,让人移动到点击位置

在这里插入图片描述



版权声明:本文为LIQIANGEASTSUN原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。