Unity导航

Posted 不思量自难忘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity导航相关的知识,希望对你有一定的参考价值。

  在如今当下的互联网时代背景下,Unity3D作为游戏开发的主要工具,为我们游戏开发提供了诸多便利.

  说到游戏我们不得不提到一个不可或缺的组成部分:导航系统;

      NavMesh(导航网格)是3D游戏世界中用于实现动态物体自动寻路的一种技术,从而实现游戏自动寻路的功效.

那我们今天就来搭建一个简单的自动寻路的导航系统:

首先:我们要有一个可以供我们游戏物体移动的游戏场景,如:一个Plane或者一个Scene;

这里,作者使用了一个简单的塔防场景;

游戏场景设置好了,我们下一步做什么呢?

   找到检视窗口点击Navigation烘焙路径; 当然我们这里要将我们要烘焙的游戏物体呢,设置为Static;当然不需要有路径的地方就不需要设置Static了;

设置好了以后一定要记得点击下方的Bake烘焙;

 

第二步: 给我们的player设置一个StartPoint(起始点)和EndPoint(目标点);  

这里使用空物体来创建起始点和目标点,并为了方便查看给它们添加标记;

好了,起始点和目标点设置好了,那我们就要对player进行操作了;

因为我们这里要让player在行进的途中有行走操作,所以我们要用到动画; 动画还记得吗? idle,walk

 

第三步:拖一个player模型到参差视图中,添加Nav Mesh Agent组件,并为它设置Animator中的Controller(动画状态机);

 

双击打开进行编辑状态机; 将idle状态和walk状态拖到状态机里面,并设置idle为最初始状态 ,并设置状态参数,这里我们使用的是int;

 

 

 

 

 

 

然后将我们设置好的状态机设置给我们的Player;

 

 

第四步:添加让player移动和播放动画的脚本;然后将player拖成预设体,将原来层次视图中的player删除;

 

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 using UnityEngine.AI;
 5 
 6 public class PlayerMoveScript : MonoBehaviour {
 7     
 8     private Animator playerAnimator;
 9     private NavMeshAgent agent;  // 用来接收获得的组件
10     private float time; // 计时
11     private int index; 
12     private int move; // 用来转换哈希值
13 
14 //    public Transform[] targetPoint;
15     public Transform endPoint;  // 设置目的地
16 
17     void Start () {
18         // 获得自动寻路的组件
19         agent = GetComponent<NavMeshAgent> ();
20         // 获得动画的组件
21         playerAnimator = GetComponent<Animator> ();
22         //转换哈希值
23         move = Animator.StringToHash ("Move");
24 
25     }
26 
27     void Update () {
28 
29         time+=Time.deltaTime;
30         // 一开始有1秒的idle时间
31         if (time >= 1.0f) {
32             // 如果开始生成的时候处于idle状态
33             if (playerAnimator.GetCurrentAnimatorStateInfo (0).shortNameHash == Animator.StringToHash ("idle")) {
34                 //设置状态参数,并开始移动的动画;
35                 playerAnimator.SetInteger (move,1);
36                 // 设置目标点
37                 agent.destination = endPoint.position;
38             }
39         }
40         //如果起始点和终止点的位置距离为0
41         if (agent.remainingDistance == 0) {
42             //并且现在的游戏物体处于walk状态
43             if (playerAnimator.GetCurrentAnimatorStateInfo (0).shortNameHash == Animator.StringToHash ("walk")) {
44                 //那么执行下一步动画操作,设置状态参数
45                 playerAnimator.SetInteger (move, 0);
46                 //删除游戏物体
47                 Destroy (gameObject);
48             }    
49         }
50     }
51         
52 }

这样player的一切组件和脚本准备就绪,那么下一步我们是不是就要生成player!(因为我们player是预设体);

 

第五步:生成player(在StartPiont位置生成);建立一个空物体来放置脚本

 1 using System.Collections;
 2 using System.Collections.Generic;
 3 using UnityEngine;
 4 
 5 public class CreatPlayerScript : MonoBehaviour {
 6 
 7     public GameObject PlayerPerfabs; // 预设体
 8     public Transform startPoint; // 开始生成预设体的位置
 9     public Transform endPoint; //目标位置
10 
11     void Start () {
12         
13     }
14     
15     void Update () {
16         //按下鼠标左键做什么事情
17         if (Input.GetMouseButtonDown (0)) {
18             //在startPoint位置生成预设体,并让预设体不能旋转;
19             GameObject Player = Instantiate (PlayerPerfabs, startPoint.position, Quaternion.identity)as GameObject;
20             // 设置目标点
21             Player.GetComponent<PlayerMoveScript> ().endPoint = endPoint;
22         }
23         
24     }
25 }

然后将我们外联进行设置;

 

我们可以创建一个Camera给我们的player,设置好位置,就可以去Game场景去查看我们的效果了.

好了,一个简单的导航就实现了,当然了小伙伴们可以去试试给游戏场景添加一个MiniMap(小地图);

 

注意:我们在做小地图的时候呢,为了不占用过多资源(就是优化嘛);可以将我们的小地图的Camera的渲染层数减少;进行一个优化

 

以上是关于Unity导航的主要内容,如果未能解决你的问题,请参考以下文章

Android底部导航片段问题

使用 NavController 从片段导航到另一个片段

addToBackStack 没有导航回正确的片段

使用底部导航栏防止片段刷新

导航上的片段生命周期重叠

在导航抽屉关闭之前加载片段