1. 程式人生 > >Unity NavMesh動態烘培和繪製

Unity NavMesh動態烘培和繪製

前提:隨著Unity5.6的推出,我們終於迎來了NavMesh的動態烘培,我們期待已久的功能終於來了,不用再研究A*演算法了,話說改進的網格尋路更加方便高效。

下面就直接進入正題:

首先場景中的物體都要掛上這個指令碼NavMeshSourceTag.cs

  1. using UnityEngine;  
  2. using UnityEngine.AI;  
  3. using System.Collections.Generic;  
  4. // Tagging component for use with the LocalNavMeshBuilder
  5. // Supports mesh-filter and terrain - can be extended to physics and/or primitives
  6. [DefaultExecutionOrder(-200)]  
  7. publicclass NavMeshSourceTag : MonoBehaviour  
  8. {  
  9.     // Global containers for all active mesh/terrain tags
  10.     publicstatic List<MeshFilter> m_Meshes = new List<MeshFilter>();  
  11.     publicstatic List<Terrain> m_Terrains = new List<Terrain>();  
  12.     void
     OnEnable()  
  13.     {  
  14.         var m = GetComponent<MeshFilter>();  
  15.         if (m != null)  
  16.         {  
  17.             m_Meshes.Add(m);  
  18.         }  
  19.         var t = GetComponent<Terrain>();  
  20.         if (t != null)  
  21.         {  
  22.             m_Terrains.Add(t);  
  23.         }  
  24.     }  
  25.     void
     OnDisable()  
  26.     {  
  27.         var m = GetComponent<MeshFilter>();  
  28.         if (m != null)  
  29.         {  
  30.             m_Meshes.Remove(m);  
  31.         }  
  32.         var t = GetComponent<Terrain>();  
  33.         if (t != null)  
  34.         {  
  35.             m_Terrains.Remove(t);  
  36.         }  
  37.     }  
  38.     // Collect all the navmesh build sources for enabled objects tagged by this component
  39.     publicstaticvoid Collect(ref List<NavMeshBuildSource> sources)  
  40.     {  
  41.         sources.Clear();  
  42.         for (var i = 0; i < m_Meshes.Count; ++i)  
  43.         {  
  44.             var mf = m_Meshes[i];  
  45.             if (mf == nullcontinue;  
  46.             var m = mf.sharedMesh;  
  47.             if (m == nullcontinue;  
  48.             var s = new NavMeshBuildSource();  
  49.             s.shape = NavMeshBuildSourceShape.Mesh;  
  50.             s.sourceObject = m;  
  51.             s.transform = mf.transform.localToWorldMatrix;  
  52.             s.area = 0;  
  53.             sources.Add(s);  
  54.         }  
  55.         for (var i = 0; i < m_Terrains.Count; ++i)  
  56.         {  
  57.             var t = m_Terrains[i];  
  58.             if (t == nullcontinue;  
  59.             var s = new NavMeshBuildSource();  
  60.             s.shape = NavMeshBuildSourceShape.Terrain;  
  61.             s.sourceObject = t.terrainData;  
  62.             // Terrain system only supports translation - so we pass translation only to back-end
  63.             s.transform = Matrix4x4.TRS(t.transform.position, Quaternion.identity, Vector3.one);  
  64.             s.area = 0;  
  65.             sources.Add(s);  
  66.         }  
  67.     }  
  68. }  

然後新建個空物體掛上指令碼:My_LocalNavMeshBuilder.cs,我這裡修改了下,就重新整理一次,所以m_Size要框住場景,再加上Msh 和MeshFilter,這是用來繪製NavMesh的。
  1. using UnityEngine;  
  2. using UnityEngine.AI;  
  3. using System.Collections;  
  4. using System.Collections.Generic;  
  5. using NavMeshBuilder = UnityEngine.AI.NavMeshBuilder;  
  6. // Build and update a localized navmesh from the sources marked by NavMeshSourceTag
  7. [DefaultExecutionOrder(-102)]  
  8. publicclass My_LocalNavMeshBuilder : MonoBehaviour  
  9. {  
  10.     // The center of the build
  11.     public Transform m_Tracked;  
  12.     // The size of the build bounds
  13.     public Vector3 m_Size = new Vector3(80.0f, 20.0f, 80.0f);  
  14.     NavMeshData m_NavMesh;  
  15.     AsyncOperation m_Operation;  
  16.     NavMeshDataInstance m_Instance;  
  17.     List<NavMeshBuildSource> m_Sources = new List<NavMeshBuildSource>();  
  18.     private MeshFilter mf;  
  19.     private Mesh m;  
  20.     //IEnumerator Start()
  21.     //{
  22.     //    while (true)
  23.     //    {
  24.     //        UpdateNavMesh(true);
  25.     //        yield return m_Operation;
  26.     //    }
  27.     //}
  28.     void Start()  
  29.     {  
  30.         mf = GetComponent<MeshFilter>();  
  31.         m = mf.mesh;  
  32.     }  
  33.     void Update()  
  34.     {  
  35.         if(Input.GetKey(KeyCode.A))  
  36.         {  
  37.             bake();  
  38.         }  
  39.         if(Input.GetKey(KeyCode.D))  
  40.         {  
  41.             drawNavMesh();  
  42.         }  
  43.     }  
  44.     privatevoid bake()  
  45.     {  
  46.         m_NavMesh = new NavMeshData();  
  47.         m_Instance = NavMesh.AddNavMeshData(m_NavMesh);  
  48.         if (m_Tracked == null)  
  49.             m_Tracked = transform;  
  50.         UpdateNavMesh(false);  
  51.     }  
  52.     privatevoid drawNavMesh()  
  53.     {  
  54.         NavMeshTriangulation nt = NavMesh.CalculateTriangulation();  
  55.         m.vertices = nt.vertices;  
  56.         m.triangles = nt.indices;  
  57.     }  
  58.     //void OnEnable()
  59.     //{
  60.     //    // Construct and add navmesh
  61.     //    m_NavMesh = new NavMeshData();
  62.     //    m_Instance = NavMesh.AddNavMeshData(m_NavMesh);
  63.     //    if (m_Tracked == null)
  64.     //        m_Tracked = transform;
  65.     //    UpdateNavMesh(false);
  66.     //}
  67.     //void OnDisable()
  68.     //{
  69.     //    // Unload navmesh and clear handle
  70.     //    m_Instance.Remove();
  71.     //}
  72.     void UpdateNavMesh(bool asyncUpdate = false)  
  73.     {  
  74.         NavMeshSourceTag.Collect(ref m_Sources);  
  75.         var defaultBuildSettings = NavMesh.GetSettingsByID(0);  
  76.         var bounds = QuantizedBounds();  
  77.         if (asyncUpdate)  
  78.             m_Operation = NavMeshBuilder.UpdateNavMeshDataAsync(m_NavMesh, defaultBuildSettings, m_Sources, bounds);  
  79.         else
  80.             NavMeshBuilder.UpdateNavMeshData(m_NavMesh, defaultBuildSettings, m_Sources, bounds);  
  81.     }  
  82.     static Vector3 Quantize(Vector3 v, Vector3 quant)  
  83.     {  
  84.         float x = quant.x * Mathf.Floor(v.x / quant.x);  
  85.         float y = quant.y * Mathf.Floor(v.y / quant.y);  
  86.         float z = quant.z * Mathf.Floor(v.z / quant.z);  
  87.         returnnew Vector3(x, y, z);  
  88.     }  
  89.     Bounds QuantizedBounds()  
  90.     {  
  91.         // Quantize the bounds to update only when theres a 10% change in size
  92.         var center = m_Tracked ? m_Tracked.position : transform.position;  
  93.         returnnew Bounds(Quantize(center, 0.1f * m_Size), m_Size);  
  94.     }  
  95.     void OnDrawGizmosSelected()  
  96.     {  
  97. 相關推薦

    Unity NavMesh動態繪製

    前提:隨著Unity5.6的推出,我們終於迎來了NavMesh的動態烘培,我們期待已久的功能終於來了,不用再研究A*演算法了,話說改進的網格尋路更加方便高效。 下面就直接進入正題: 首先場景中的物體都要掛上這個指令碼NavMeshSourceTag.cs

    Unity NavMesh尋路檢測的bug(或者特性),爬坡卡住問題。(角色高度網格高度不一致造成)

    Unity專案,由於人物移動時一般用搖桿或者方向鍵控制, 需要有八方向方式控制朝向,  所以沒有用 NavMesh Agent, 而是自己控制人物方向移動,然後貼合地面。 用了NavMesh.CalculatePath只是用於目標點的尋路, 尋找出路經後自己計算實現移動。

    [專欄精選]Unity動態構建NavMesh

    本文節選自洪流學堂公眾號專欄《鄭洪智的Unity2018課》,未經允許不可轉載。 洪流學堂公眾號回覆專欄,檢視更多專欄文章。 小新:“Unity內建的Navigation系統是不錯,挺好用,但是我發現個致命問題” 大智:“說說看?” 小新:“導航系統對於靜態場

    unity標準材質球動態改值共用材質不同設定問題

    可以用SetPropertyBlock方式來實現多個物體共享材質,有部分屬性略有不同的情況 這種方式被用在unity的地形上,裡面的樹就是通過這種方式實現不同樹共用材質, 卻可以有不同的顏色傾向,風力

    UnityUnity資源池的動態載入釋放記憶體優化處理

    需求環境         在上一級的【解決方案】文章中,我們設計出了動態載入資源的業務流程,而這一節,我們就通過一些簡單的程式碼,來實現出業務流程中的效果。        吸取之前文章的經驗,如

    動態載入貼圖與Terrain轉mesh

    前言 unity載入烘培貼圖是需要載入場景才可以使用,但如果專案只使用一個場景或者有許多關卡地形時,明顯通過載入場景來達到更換烘培貼圖的這種做法是不妥當的。而terrain地形在有些安卓機上的支援並不是很好,所以有必要把地形轉為網格。慶幸的是,網上也有這方面的

    【個人Unity筆記】焙光照貼圖後保留法線光探頭

    使用的5.34f1版本的unity 有時候為了節省開銷,烘焙光照貼圖是一種很好的辦法,在手機上開發經常會使用到,配合光探頭還可以讓靜態光和非靜態物體產生互動。 首先,把要烘焙的物體全部勾選為靜態(Static)。 然後,把需要烘焙的光的Baking由預

    unity法線貼圖,光線的應用

    法線貼圖 法線貼圖是比較常用的一種貼圖,作用是使一些面數比較少的模型的紋理更加的精緻和逼真。這樣在大幅度減少了執行的效能消耗,也能達到比較好的遊戲畫面。unity3d中有比較簡單的法線貼圖,就是看起來與3D效果無異的2D貼圖。如果做3D模型的話,就會浪費顯示晶

    C++筆記(12):動態內存智能指針

    style round 運算 span tro 運算符 delet 庫函數 針對                           動態內存和智能指針 動態內存:   1.針對堆裏面存放的對象   2.使用new delete運算符   3.智能指針:shared_ptr

    C++中虛函數的動態綁定多態性

    gif alt eric 可能 運行 lan event 重要 ostream 目錄 靜態類型VS動態類型,靜態綁定VS動態綁定兩組概念 虛函數的實現機制 多態性 一.靜態 vs 動態   靜態類型 VS 動態類型。靜態類型指的是對象聲

    Unity Shader 基本類型結構

    pla prop 文章 ack 遊戲 end 轉換 效果 black 最近看了siki老師的shader教程,感謝siki老師,講課真好。之前看了一些Shader的書,因為沒有圖形學的基礎,所以看的挺痛苦的。然後看了siki老師的視頻後,結合以前看的書一下子明了了。 在這裏

    C#—Dev XtraTabControl動態增加Tab關閉選項卡方法

    按鈕 屬性 bool new express controls dispose lean 選中 C#—Dev XtraTabControl動態增加Tab和關閉選項卡方法,有需要的朋友可以參考下。 記錄一下以免以後忘了 添加using DevExpress.XtraTab;

    python基礎學習日誌day8-動態導入斷言

    onerror 學習日誌 動態 nbsp error print 變量 alex 重要 一:動態導入importlib 在程序運行的過程中,根據變量或者配置動態的決定導入哪個模塊,可以使用模塊importlib importlib使用示例 二:斷言assert

    Android動態添加移除布局

    dmi ase min pan wid ide state idg system 1 package com.hyang.administrator.studentproject; 2 3 import android.os.Bundle; 4 import a

    NavMesh動態碰撞

    void tor enter 動態添加 pre .com this div parent 今天遇到一個問題,就是怎樣處理一些動態的障礙物。NavMesh是能夠躲避靜態的障礙物。NavMeshObstacle的作用就是動態添加障礙。可是有個問題,NavMeshObst

    js動態添加刪除標簽

    list 賦值 cti tee reat 取值 setattr element nbsp html代碼 <h1>動態添加和刪除標簽</h1> <div id="addTagTest"> <table>

    [Unity Shader] 逐頂點光照逐片元光照

    空間 col dba orm 開始 光照模型 著色器 素數 ima   書中的6.4節講的是漫反射的逐頂點光照和逐片元光照。   前一種算法是根據漫反射公式計算頂點顏色(頂點著色器),對顏色插值(光柵化過程)返回每個像素的顏色值(片元著色器)。   第二種算法是獲得頂點

    關於Unity中NGUI的Pivot錨點

    wid height http -1 貼圖 關於 位置 ngui 技術 Pivot 創建一個Sprite1節點,關聯一個圖集和一張貼圖,用圖中的六個按鈕調整這個貼圖的Pivot點,一共有八個點可以選擇 再創建一個Sprite2節點,作為Sprite1節點的子節點,關聯一個圖

    Unity 5實戰 使用C#Unity開發多平臺遊戲pdf

    name clas position ati 下載地址 組件 inspector ins over 下載地址:城通網盤 作者簡介編輯 Joseph Hocking是一位交互式媒體開發方面的軟件工程師。他就職於Synapse Games公司並在芝加哥哥倫比亞學院教授遊戲開發

    C++相關:動態內存智能指針

    數量 網絡 隱式 執行 動態分配 int 弱引用 支持 相關操作 前言 在C++中,動態內存的管理是通過運算符new和delete來完成的。但使用動態內存很容易出現問題,因為確保在正確的時間釋放內存是及其困難的。有時候我們會忘記內存的的釋放,這種情況下就會產生內存泄露;有時