Unity NavMesh动态烘培和绘制
来源:互联网 发布:Linux下配置gnu 编辑:程序博客网 时间:2024/05/01 17:28
前提:随着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;// Tagging component for use with the LocalNavMeshBuilder// Supports mesh-filter and terrain - can be extended to physics and/or primitives[DefaultExecutionOrder(-200)]public class NavMeshSourceTag : MonoBehaviour{ // Global containers for all active mesh/terrain tags 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); } } // Collect all the navmesh build sources for enabled objects tagged by this component 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; // Terrain system only supports translation - so we pass translation only to back-end 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;// Build and update a localized navmesh from the sources marked by NavMeshSourceTag[DefaultExecutionOrder(-102)]public class My_LocalNavMeshBuilder : MonoBehaviour{ // The center of the build public Transform m_Tracked; // The size of the build bounds 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; //IEnumerator Start() //{ // while (true) // { // UpdateNavMesh(true); // yield return m_Operation; // } //} 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 OnEnable() //{ // // Construct and add navmesh // m_NavMesh = new NavMeshData(); // m_Instance = NavMesh.AddNavMeshData(m_NavMesh); // if (m_Tracked == null) // m_Tracked = transform; // UpdateNavMesh(false); //} //void OnDisable() //{ // // Unload navmesh and clear handle // m_Instance.Remove(); //} 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() { // Quantize the bounds to update only when theres a 10% change in size 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组件,就可以控制人物寻路了。
最后附上工程文件,象征性的收取点手续费,点击下载
1 0
- Unity NavMesh动态烘培和绘制
- Unity NavMesh动态烘培和绘制
- [Unity][NavMesh]Unity NavMesh Compent 寻路组件动态自动烘培
- Unity5.6新功能High-level NavMesh之实时动态烘培NavMesh
- unity烘培
- unity烘培
- 【Unity】模型烘培参数
- unity 遮挡剔除 和烘赔参数
- [资源分享]NavMeshComponents(Unity官方插件)动态创建自动烘培地形
- Unity 光影烘培资料集合
- unity烘培贴图黑斑问题
- Unity:Navmesh
- Unity Navmesh
- Unity-NavMesh
- Unity5动态加载烘培场景
- Unity 烘赔
- Unity3D教程:Unity批量处理修改烘培LightMap
- Unity3D之动态修改烘培贴图的大小&脚本烘培场景
- Bootstrap中水平排列的表单form-inline
- SpringMVC之DispatcherServlet类
- 浅谈AndroidManifest文件的android:allowBackup属性
- JAVA中toString方法的作用
- 7637
- Unity NavMesh动态烘培和绘制
- SpringMVC之一个简单的例子
- HashSet与TreeSet
- Java的从浅至深绕坑而行的学习
- 20120531
- Map,HashMap,TreeMap
- MySQL Workbench建表时 PK NN UQ BIN UN ZF AI 的含义
- 在Window下安装Oracle
- 关于大学生选择哪种编程语言