Skip to content

Instantly share code, notes, and snippets.

@tsubaki
Created May 5, 2017 12:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tsubaki/1d78ef2e5f25e63af00459644768b320 to your computer and use it in GitHub Desktop.
Save tsubaki/1d78ef2e5f25e63af00459644768b320 to your computer and use it in GitHub Desktop.
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
public class MyNavmeshBuilder : MonoBehaviour {
public Transform tracker;
public Vector3 size = new Vector3(80.0f, 20.0f, 80.0f);
public int agentTypeID;
public float q = 0.1f;
NavMeshData navMesh;
AsyncOperation asyncOperation;
NavMeshDataInstance navmeshDataInstance;
List<NavMeshBuildSource> source = new List<NavMeshBuildSource>();
IEnumerator onUpdateEnumrator;
IEnumerator OnUpdate()
{
while (true)
{
UpdateNavMesh();
yield return asyncOperation;
}
}
private void Awake()
{
navMesh = new NavMeshData();
CollectSource();
onUpdateEnumrator = OnUpdate();
}
private void OnEnable()
{
navmeshDataInstance = NavMesh.AddNavMeshData(navMesh);
UpdateNavMesh(false);
StartCoroutine(onUpdateEnumrator);
}
private void OnDisable()
{
navmeshDataInstance.Remove();
StopCoroutine(onUpdateEnumrator);
}
void CollectSource()
{
source.Clear();
foreach( var mesh in transform.GetComponentsInChildren<MeshFilter>())
{
var m = mesh.sharedMesh;
if (m == null) continue;
var s = new NavMeshBuildSource();
s.shape = NavMeshBuildSourceShape.Mesh;
s.sourceObject = m;
s.transform = mesh.transform.localToWorldMatrix;
s.area = 0;
source.Add(s);
}
}
void UpdateNavMesh(bool asyncUpdate = true)
{
var settings = NavMesh.GetSettingsByID(agentTypeID);
var bounds = QuantizedBounds();
if (asyncUpdate)
asyncOperation = NavMeshBuilder.UpdateNavMeshDataAsync(navMesh, settings, source, bounds);
else
NavMeshBuilder.UpdateNavMeshData(navMesh, settings, source, 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 = tracker ? tracker.position : transform.position;
return new Bounds(Quantize(center, q * size), size);
}
void OnDrawGizmosSelected()
{
if (navMesh)
{
Gizmos.color = Color.green;
Gizmos.DrawWireCube(navMesh.sourceBounds.center, navMesh.sourceBounds.size);
}
Gizmos.color = Color.yellow;
var bounds = QuantizedBounds();
Gizmos.DrawWireCube(bounds.center, bounds.size);
}
}
@kinopek
Copy link

kinopek commented Oct 8, 2020

Great stuff! How do I use it? Should I assign it to some GameObject and it will do the work? Or should I invoke some method from it?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment