Unity 专业 Navigation导航系统
发表于2017-01-14
1、Navigation系统的使用原理
NavMesh(导航网格)是3D游戏世界中用于实现动态物体自动寻路的一种技术,将游戏中复杂的结构组织关系简化为带有一定信息的网格,在这些网格的基础上通过一系列的计算来实现自动寻路。
2、自动寻路:NavMesh创建与NavMeshAgent组件的添加
2.1搭建场景
2.2设置场景物体为导航静态 Navigation Static
2.3创建NavMesh
打开Navigation视图窗口Window -> Navigation调整参数
Radius
Height
StepHeight
点击“Bake”按钮,生成导航网格.
2.3添加NavMeshAgent
在场景中添加两个物体分别代表Player和target.为Player添加NavMeshAgent组件
再添加脚本NavMeshTest
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using UnityEngine; using System.Collections; public class NavMeshTest : MonoBehaviour { NavMeshAgent agent; public GameObject Target; void Start () { agent = GetComponent } void Update() { agent.SetDestination(Target.transform.position); } }
|
拖入Target,运行就可以寻路了.
3、分离路面的链接:Off Mesh Link的使用
3.1自动Off Mesh Link的创建
选择作为高台的Cube在Navigation窗口的Object选项卡中勾选OffMeshLink Generation ☑将Bake选项卡参数Drop Height设为100Player的Cube放置在高台上,把作为Target的Cube放置在高台下。
这样player就能从高台跳下来了
3.2手动Off Mesh Link的实现
添加起始点终止点Start 和End,为起始点(start point)添加Off Mesh Link组件
把起始点和结束点分别拖拽到 Start 和End属性栏中。
然后运行,观察效果
4、联通路面的分离:Navigation系统的分层烘焙方式
4.1NavMesh的分层烘焙
新建场景
设置烘焙层
修改Navigation的Object选项卡中的Navigation Layer进行烘焙
在Player的Nav Mesh Agent组件的NavMesh Walkable中取消选项qiao3或qiao4,
运行观察效果。
5、动态路面的实现:使用脚本完成动态路面寻路系统
为桥加脚本代码,控制桥的消失和出现。并动态修改NaMeshAgent组件中的SetAreaCost属性来更
改物体的可行进区域。
1 | agent.SetAreaCost(NavMesh.GetAreaFromName( "qiao3" ), 4); |
6、动态路障的实现:使用Navmesh Obstacle组件
为桥体添加Nav Mesh Obstacle组件
调整大小中心类型,就形象障碍物了.
运行观察效果
7、其他效果的实现
如果再结合动画效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | using UnityEngine; using System.Collections; public class Aman : MonoBehaviour { public Animator animator; public GameObject poli; private NavMeshAgent agent; public GameObject obj; void Start () { agent = GetComponent animator = GetComponent } void Update () { agent.SetDestination(obj .transform .position); agent.SetAreaCost(NavMesh.GetAreaFromName( "qiao3" ), 4); if (Input.GetKey(KeyCode.W)) { poli.transform.Translate(transform .forward *Time .deltaTime *0.2f ); animator.SetBool ( "walk" , true ); } else { animator.SetBool( "walk" , false ); } if (Input.GetKey(KeyCode.S)) { poli.transform.Translate(transform.forward * Time.deltaTime * 0.4f); animator.SetFloat( "Speed" , 10f); } else { animator.SetFloat( "Speed" , 0f); } if (agent.remainingDistance <= 3) { animator.SetFloat( "Speed" , 0f); } else { animator.SetFloat( "Speed" , 10f); } } } |
可以实现很多效果,自己发挥吧.还有,如果再导航范围内可以动态更改目标位置比如点击更改目标位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | using UnityEngine; using System.Collections; public class dndn : MonoBehaviour { RaycastHit hit; Ray ray; Vector3 dir; public GameObject obj; void Start () { } void Update () { if (Input .GetMouseButtonDown (0)) { ray = Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics .Raycast (ray , out hit )) { dir = new Vector3(hit.point.x, hit.transform.position.y, hit.point.z); Debug.Log(dir); obj.transform.position = dir; } } } } |