Unity 专业 Navigation导航系统

发表于2017-01-14
评论2 5.1k浏览
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;
            }
        }
          
      
        }
}

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引