学习归纳自用嘻嘻~
一、概述
导航系统可以智能的使游戏角色在场景中自由移动,寻路系统算做求解型AI,同样常见的寻路算法还有A*寻路。Unity中的导航系统允许我们在运行时动态的创建障碍,自动创建导航网格,动态规划路径,对于非连接的网格可以构建特殊的操作等。
二、组件
1、四大组件概述
- NavMesh:用来描述一个可行走区域的数据结构,这个数据是需要我们手动设置生成(baked),或者动态生成(代码控制)。
- NavMeshAgent:用来帮助游戏中的角色移动到指定目标的组件,它使用的是NavMesh数据,并且知道如何规划最优路径,避开障碍物等。
- Off-MeshLink:用于手动指定路线来生成分离的网格连接。例如,游戏中让行进对象上下爬梯子到达另一块网格的情景就是利用生成分离的网格连接来实现的。
- NavMeshObstacle:这个组件是用来给需要导航的世界设置障碍的,如图中所示,当障碍物静止在地面上时,会在导航区域内扣除一个洞。
2、高级组件概述
一些更高级的导航组件没有内置在Unity标准资源中,需要前往Github自行下载
同样也是由四个高级组件构成
- NavMeshSurface:感觉是对标的NaMesh系统,使用这个组件后会更方便,直接在需要进行导航的场景的父节点挂载这个组件就可以完成数据的bake,不再需要指定手动指定,而且会更方便管理导航的路径。
- NavMeshModifier:是用来配合NavMesh Surface使用的,在子层级上添加该组件后,直接修改这个组件会影响子层级下的所有场景物体,比如可以指定某类型的角色在该区域是不可以移动的。
- NavMeshModifierVolume:同样也是用来配合NavMesh Surface使用的,区别于NavMesh Modifier,该组件会创建一个体积盒,类似于碰撞盒,该体积盒包含的区域都会受到该组件参数的影响。比如放置一个该组件的体积盒,并设置为不可移动类型,在bake后,该组件体积盒所在区域都变为不可移动区域。
- NavMeshLink:感觉对标的是Off-MeshLinks,添加该组件的场景物体会使接触到的两个不连通的NavMesh之间形成通路。
简而言之,这四个高级组件是对导航系统的组件化,提升了对自动导航系统使用的便捷性和更多可能性。
配合高级导航组件提供的场景案例,我们可以使用这些功能,制作动态路径的控制。
三、设置导航目的地
1、直接设置
using UnityEngine;
public class MoveDestination : MonoBehaviour {
public Transform goal;
void Start () {
NavMeshAgent agent = GetComponent<NavMeshAgent>();
agent.destination = goal.position;
}
2、通过鼠标点击设置
using UnityEngine;
using UnityEngine.AI;
public class MoveToClickPoint : MonoBehaviour {
NavMeshAgent agent;
void Start() {
agent = GetComponent<NavMeshAgent>();
}
void Update() {
if (Input.GetMouseButtonDown(0)) {
RaycastHit hit;
if (Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit, 100)) {
agent.destination = hit.point;
}
}
}
}
3、设置巡逻点
using UnityEngine;
using UnityEngine.AI;
using System.Collections;
public class Patrol : MonoBehaviour {
public Transform[] points;
private int destPoint = 0;
private NavMeshAgent agent;
void Start () {
agent = GetComponent<NavMeshAgent>();
// Disabling auto-braking allows for continuous movement
// between points (ie, the agent doesn't slow down as it
// approaches a destination point).
agent.autoBraking = false;
GotoNextPoint();
}
void GotoNextPoint() {
// Returns if no points have been set up
if (points.Length == 0)
return;
// Set the agent to go to the currently selected destination.
agent.destination = points[destPoint].position;
// Choose the next point in the array as the destination,
// cycling to the start if necessary.
destPoint = (destPoint + 1) % points.Length;
}
void Update () {
// Choose the next destination point when the agent gets
// close to the current one.
if (!agent.pathPending && agent.remainingDistance < 0.5f)
GotoNextPoint();
}
}