[沐冉楠] Unity 专业 Navigation导航系统
本帖最后由 沐冉楠 于 2017-1-10 16:57 编辑

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
[mw_shl_code=csharp,true]using UnityEngine;
using System.Collections;

public class NavMeshTest : MonoBehaviour {
   
   
    NavMeshAgent agent;
    public GameObject Target;
  
        void Start () {
          agent = GetComponent<NavMeshAgent>();
        
        }

    void Update()
    {
        agent.SetDestination(Target.transform.position);
    }
}
[/mw_shl_code]


拖入Target,运行就可以寻路了.


3.分离路面的链接:Off Mesh Link的使用
3.1自动Off Mesh Link的创建
选择作为高台的Cube
在Navigation窗口的Object选项卡中
勾选OffMeshLink Generation ☑
将Bake选项卡参数Drop Height设为100
Player的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属性来更

改物体的可行进区域。
[mw_shl_code=csharp,true]agent.SetAreaCost(NavMesh.GetAreaFromName("qiao3"), 4);[/mw_shl_code]

6.动态路障的实现:使用Navmesh Obstacle组件

为桥体添加Nav Mesh Obstacle组件


调整大小中心类型,就形象障碍物了.

运行观察效果

7.其他效果的实现

如果再结合动画效果
[mw_shl_code=csharp,true]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<NavMeshAgent>();
        animator = GetComponent<Animator>();
        }
        
        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);
        }
        }

}
[/mw_shl_code]

可以实现很多效果,自己发挥吧.
还有,如果再导航范围内可以动态更改目标位置
比如点击更改目标位置
[mw_shl_code=csharp,true]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;
            }
        }
        
   
        }
}
[/mw_shl_code]










精致学习了哈
gkjjjjyyyyyyyyuuui
  • 地板 寸辵
  • 2017-1-11 08:34:14
留爪!!有用!!前来学习,谢谢!!
  • 5# mytool
  • 2017-1-11 09:32:21
精致学习了哈
看完了 ,还不是有点不懂
习惯性留名~
  • 8# Mill
  • 2017-1-11 09:51:19
等我吃回来早饭,一定要学习一下。
学习学习
  • 10# Nature
  • 2017-1-11 10:26:00
这专业个毛啊。很基本嘛。
学习学习
学习了,感谢
先收藏着,慢慢学习
  • 14# 825
  • 2017-1-11 11:09:35
最喜欢这样的帖子了
最近就在用寻路 很有帮助!感谢!
12下一页