小言_互联网的博客

Unity AI导航寻路系统

447人阅读  评论(0)

第一步搭建场景

两个平面,一个立方体,一个胶囊,一座桥(立方体)

让这个胶囊自主找立方体

将除胶囊外其他场景中物体设为静态 

打开AI导航

烘培一个导航网格

给胶囊添加智能体

编辑AI寻路脚本


   
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. public class AINavigation : MonoBehaviour
  6. {
  7. public GameObject target;
  8. private NavMeshAgent agent;
  9. // Start is called before the first frame update
  10. void Start()
  11. {
  12. agent = GetComponent<NavMeshAgent>();
  13. agent.destination = target.transform.position;
  14. }
  15. // Update is called once per frame
  16. void Update()
  17. {
  18. }
  19. }

脚本绑定胶囊上

指定cube

效果

现在要实现另一个功能,就是鼠标点击哪儿,物体就往哪儿走。

这个功能在游戏中很常用。

发射一个射线,射线和地板相交的点,就是要走到的位置。

代码


   
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. public class AINavigation : MonoBehaviour
  6. {
  7. public GameObject target;
  8. private NavMeshAgent agent;
  9. // Start is called before the first frame update
  10. void Start()
  11. {
  12. agent = GetComponent<NavMeshAgent>();
  13. agent.destination = target.transform.position;
  14. }
  15. // Update is called once per frame
  16. void Update()
  17. {
  18. if(Input.GetMouseButton( 0))
  19. {
  20. RaycastHit hit;
  21. if(Physics.Raycast(Camera.main.ScreenPointToRay(Input.mousePosition), out hit))
  22. {
  23. agent.destination = hit.point;
  24. }
  25. }
  26. }
  27. }

效果

鼠标点击哪就走到哪儿,有内味儿了

而且还可以自动避障哦

按下图修改场景

桥*2、胶囊*2

新增的桥设置静态

场景已改变,自主导航网格需要重新烘培


效果

默认走最短路径

面板解释

跳跃不超过0.4m,坡度不超过45°

自动导航的相关限制参数

现在让一个胶囊指定走一个桥,不能走另一个

选择胶囊,设置智能寻路属性

能走哪些区域,不能走哪些区域,设置好

指定两个桥的导航所属区域,一个front,一个back

一定要记住,修改参数后要重新烘焙

区域图

效果

搭建场景然后烘培

正常情况下,这两个胶囊会在墙下面停下来,够不着立方体

现在要实现让两个胶囊走天路,去够它

把导航网格不连接的区域把它link起来

给那个cube添加off mesh link组件

再烘培一下

已连接

但是现在还是原样,不能够着

要设置烘培高度

烘培后区域变化

效果

这个cube只是作为一个连接物,并不从上面过(逻辑有点奇怪)

导航障碍组件

修改场景

为桥添加导航障碍组件

编写脚本


   
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. public class NMOCtrl : MonoBehaviour
  6. {
  7. private NavMeshObstacle obs;
  8. // Start is called before the first frame update
  9. void Start()
  10. {
  11. obs = this.GetComponent<NavMeshObstacle>();
  12. obs.enabled = true;
  13. }
  14. // Update is called once per frame
  15. void Update()
  16. {
  17. if(Input.GetButtonDown( "Fire1"))
  18. {
  19. if (obs)
  20. {
  21. obs.enabled = false;
  22. this.GetComponent<Renderer>().material.color = Color.green;
  23. }
  24. }
  25. if (Input.GetButtonUp( "Fire1"))
  26. {
  27. if (obs)
  28. {
  29. obs.enabled = true;
  30. this.GetComponent<Renderer>().material.color = Color.red;
  31. }
  32. }
  33. }
  34. }

绑定到桥上即可

修改参数

高度要大于1,不然没有阻碍效果!

效果

固定路线巡航

创建一个空对象

创建n个立方体做路径点

创建脚本


   
  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using UnityEngine.AI;
  5. public class AIPath : MonoBehaviour
  6. {
  7. public NavMeshAgent nma;
  8. public Transform[] pathpoints;
  9. int currentpointindex;
  10. // Start is called before the first frame update
  11. void Start()
  12. {
  13. nma.SetDestination(pathpoints[ 0].position);
  14. }
  15. // Update is called once per frame
  16. void Update()
  17. {
  18. if(nma.remainingDistance<nma.stoppingDistance)
  19. {
  20. currentpointindex = (currentpointindex + 1) % pathpoints.Length;
  21. nma.SetDestination(pathpoints[currentpointindex].position);
  22. }
  23. }
  24. }

AI(胶囊)

胶囊智能体指定N.M.A.

把路径点拖入下面的数组

往这个字样上拖

场景静态化并烘培

运行

效果

无限循环

有限路径代码(停在最后一个路径点)

if(nma.remainingDistance<nma.stoppingDistance && currentpointindex<(pathpoints.Length-1))

效果


转载:https://blog.csdn.net/weixin_43673589/article/details/106195195
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场