Unity NavMesh动态烘培和绘制
来源:互联网 发布:ubuntu 卸载wineqq 编辑:程序博客网 时间:2024/05/01 05:35
前提:随着Unity5.6的推出,我们终于迎来了NavMesh的动态烘培,我们期待已久的功能终于来了,不用再研究A*算法了,话说改进的网格寻路更加方便高效。
Unity5.6 更新概要(中文版):http://mt.sohu.com/it/d20170401/131548770_280780.shtml
Unity5.6更新概要(英文版):https://blogs.unity3d.com/cn/2017/03/31/5-6-is-now-available-and-completes-the-unity-5-cycle/?_ga=1.14498615.1252386216.1491371601
下面就直接进入正题:
首先场景中的物体都要挂上这个脚本NavMeshSourceTag.cs
- using UnityEngine;
- using UnityEngine.AI;
- using System.Collections.Generic;
-
-
-
- [DefaultExecutionOrder(-200)]
- public class NavMeshSourceTag : MonoBehaviour
- {
-
- public static List<MeshFilter> m_Meshes = new List<MeshFilter>();
- public static List<Terrain> m_Terrains = new List<Terrain>();
-
- void OnEnable()
- {
- var m = GetComponent<MeshFilter>();
- if (m != null)
- {
- m_Meshes.Add(m);
- }
-
- var t = GetComponent<Terrain>();
- if (t != null)
- {
- m_Terrains.Add(t);
- }
- }
-
- void OnDisable()
- {
- var m = GetComponent<MeshFilter>();
- if (m != null)
- {
- m_Meshes.Remove(m);
- }
-
- var t = GetComponent<Terrain>();
- if (t != null)
- {
- m_Terrains.Remove(t);
- }
- }
-
-
- public static void Collect(ref List<NavMeshBuildSource> sources)
- {
- sources.Clear();
-
- for (var i = 0; i < m_Meshes.Count; ++i)
- {
- var mf = m_Meshes[i];
- if (mf == null) continue;
-
- var m = mf.sharedMesh;
- if (m == null) continue;
-
- var s = new NavMeshBuildSource();
- s.shape = NavMeshBuildSourceShape.Mesh;
- s.sourceObject = m;
- s.transform = mf.transform.localToWorldMatrix;
- s.area = 0;
- sources.Add(s);
- }
-
- for (var i = 0; i < m_Terrains.Count; ++i)
- {
- var t = m_Terrains[i];
- if (t == null) continue;
-
- var s = new NavMeshBuildSource();
- s.shape = NavMeshBuildSourceShape.Terrain;
- s.sourceObject = t.terrainData;
-
- s.transform = Matrix4x4.TRS(t.transform.position, Quaternion.identity, Vector3.one);
- s.area = 0;
- sources.Add(s);
- }
- }
- }
然后新建个空物体挂上脚本:My_LocalNavMeshBuilder.cs,我这里修改了下,就刷新一次,所以m_Size要框住场景,再加上Msh 和MeshFilter,这是用来绘制NavMesh的。- using UnityEngine;
- using UnityEngine.AI;
- using System.Collections;
- using System.Collections.Generic;
- using NavMeshBuilder = UnityEngine.AI.NavMeshBuilder;
-
-
- [DefaultExecutionOrder(-102)]
- public class My_LocalNavMeshBuilder : MonoBehaviour
- {
-
- public Transform m_Tracked;
-
-
- public Vector3 m_Size = new Vector3(80.0f, 20.0f, 80.0f);
-
- NavMeshData m_NavMesh;
- AsyncOperation m_Operation;
- NavMeshDataInstance m_Instance;
- List<NavMeshBuildSource> m_Sources = new List<NavMeshBuildSource>();
-
- private MeshFilter mf;
- private Mesh m;
-
-
-
-
-
-
-
-
-
-
- void Start()
- {
- mf = GetComponent<MeshFilter>();
- m = mf.mesh;
- }
-
- void Update()
- {
- if(Input.GetKey(KeyCode.A))
- {
- bake();
- }
-
- if(Input.GetKey(KeyCode.D))
- {
- drawNavMesh();
- }
- }
-
- private void bake()
- {
- m_NavMesh = new NavMeshData();
- m_Instance = NavMesh.AddNavMeshData(m_NavMesh);
- if (m_Tracked == null)
- m_Tracked = transform;
- UpdateNavMesh(false);
- }
-
- private void drawNavMesh()
- {
- NavMeshTriangulation nt = NavMesh.CalculateTriangulation();
- m.vertices = nt.vertices;
- m.triangles = nt.indices;
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- void UpdateNavMesh(bool asyncUpdate = false)
- {
- NavMeshSourceTag.Collect(ref m_Sources);
- var defaultBuildSettings = NavMesh.GetSettingsByID(0);
- var bounds = QuantizedBounds();
-
- if (asyncUpdate)
- m_Operation = NavMeshBuilder.UpdateNavMeshDataAsync(m_NavMesh, defaultBuildSettings, m_Sources, bounds);
- else
- NavMeshBuilder.UpdateNavMeshData(m_NavMesh, defaultBuildSettings, m_Sources, bounds);
- }
-
- static Vector3 Quantize(Vector3 v, Vector3 quant)
- {
- float x = quant.x * Mathf.Floor(v.x / quant.x);
- float y = quant.y * Mathf.Floor(v.y / quant.y);
- float z = quant.z * Mathf.Floor(v.z / quant.z);
- return new Vector3(x, y, z);
- }
-
- Bounds QuantizedBounds()
- {
-
- var center = m_Tracked ? m_Tracked.position : transform.position;
- return new Bounds(Quantize(center, 0.1f * m_Size), m_Size);
- }
-
- void OnDrawGizmosSelected()
- {
- if (m_NavMesh)
- {
- Gizmos.color = Color.green;
- Gizmos.DrawWireCube(m_NavMesh.sourceBounds.center, m_NavMesh.sourceBounds.size);
- }
-
- Gizmos.color = Color.yellow;
- var bounds = QuantizedBounds();
- Gizmos.DrawWireCube(bounds.center, bounds.size);
-
- Gizmos.color = Color.green;
- var center = m_Tracked ? m_Tracked.position : transform.position;
- Gizmos.DrawWireCube(center, m_Size);
- }
- }
最后再在你的人物上面加上NavMeshAgent组件,就可以控制人物寻路了。