一、创建一个简单场景,如图
说明:Capsule代表玩家,Cube是一个动态障碍物,地面是一个Plane
下面说明下这个场景的制作过程:
1、选中Plane,并打开Window->Navigation
2、创建一个Cube作为动态障碍物,并在Cube挂个NavMeshObstacle组件。
实际开发中使用动态障碍物功能时,有一种情况需要注意:怪兽面前正好有一些紧密排列的动态障碍物时,会想要通过计算最短路径直接穿过这些动态障碍物,而不是绕过这些障碍物,要想解决这个问题,可以勾选Carve选项。
注意:
如果勾选了Carve,Unity将实时烘培导航网格,这势必增加运算负荷。因此,勾选Carve选项后,一定要通过其下方的各种属性设置以尽可能减少负荷。
Move Threshold: 模型移动某人距离后再烘培。
Time To Stationary: 指定模型在某个位置停止一段时间后再烘培。
Carve One Stationary: 勾选后,模型移动时不会实时烘培。
3、创建一个Capsule,并挂上NavMeshAgent组件以及一个自己写的用于控制玩家移动的PlayerController.cs脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
/// <summary>
/// 玩家控制器
/// </summary>
public class PlayerController : MonoBehaviour {
[SerializeField]
private NavMeshAgent m_NavMeshAgent;
void Awake () {
if(null == m_NavMeshAgent)
m_NavMeshAgent = this.GetComponent<NavMeshAgent>();
}
void Update ()
{
if (Input.GetMouseButtonDown(0))
{
//Camera.main为第一个启动的Tag为MainCamera的摄相机
//投射距离
float dist = Camera.main.farClipPlane - Camera.main.nearClipPlane;
//通过光线投射判断鼠标点中的物体
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
RaycastHit hit;
if (Physics.Raycast(ray, out hit, dist))
{
m_NavMeshAgent.ResetPath();
m_NavMeshAgent.SetDestination(hit.point);
}
}
}
}
运行测试
当Cube存在时,Capsule会绕过Cube到达目标点,当Cule不存在时(隐藏或销毁),Capsule将直接到达目标点(寻路不再受Cule影响)。