I’m building an AR experience where I receive plane anchors (just GameObjects with a child quad mesh). I’d like to turn these into navigable surfaces and have been looking at Unity.AI.Navigation. However, I’m seemingly unable to actually create a navmesh on the planes. Here is my code:
Pretty simple: I add the NavMeshSurface component and call the build function (a bit concerned that this method is not async, btw). Next, to test it out, I have a reference to a NavMeshAgent and I try to warp it to the center of that plane. But when the script that controls that agent tries to select a new destination, I get:
"GetRemainingDistance" can only be called on an active agent that has been placed on a NavMesh.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
EnemyBehavior:Update () (at Assets/Scripts/AI/EnemyBehavior.cs:90)
Indicating that a NavMesh probably has not been constructed. Using the Scene view, I don’t actually see any NavMesh geometry although the NavMeshSurface component was successfully added as expected.
I’ve also tried using the old NavMeshBuilder system but my code (which worked in Unity 5.6) no longer appears to work. No NavMesh components appear to be created and no NavMesh is visible in the Scene editor.
Not sure how much of a help this will be for you but here is a snippet of my code.
Note I also use MessageDispatcher but you could use whatever or just remove it.
You could subscribe to OnBuilt event then add your agents to the navmesh.
using com.ootii.Messages;
using System.Collections;
using Unity.AI.Navigation;
using UnityEngine;
namespace Apoth
{
public class NavigationBuilder : MonoBehaviour
{
public bool debugMode = false;
public bool gridsArePrebaked = false;
public NavMeshSurface surface;
public bool NavMeshBuilt { get; private set; } = false;
public static NavigationBuilder instance;
public static OnInitialized OnBuilt;
void Awake()
{
if (instance == null)
{
instance = this;
}
else
{
Destroy(gameObject);
return;
}
}
private void OnEnable()
{
if (debugMode)
Debug.Log("NavigationBuilder - OnEnable");
if (gridsArePrebaked)
OnNavMeshBuilt();
else
MessageDispatcher.AddListener("CreateGridMessage", OnCreateGridMessageReceived, true);
}
private void OnDisable()
{
if (debugMode)
Debug.Log("NavigationBuilder - OnDisable");
MessageDispatcher.RemoveListener("CreateGridMessage", OnCreateGridMessageReceived);
}
public void OnCreateGridMessageReceived(IMessage rMessage)
{
Debug.Log("NavigationBuilder - OnCreateGridMessageReceived");
CreateGridMessage cgm = (CreateGridMessage)rMessage.Data;
Bounds? bounds = null;
if (cgm != null)
{
bounds = cgm.dungeonBounds;
}
StartCoroutine(BuildNavMeshAfterDelay(1, bounds));
}
IEnumerator BuildNavMeshAfterDelay(float delayTime, Bounds? bounds)
{
yield return new WaitForSeconds(delayTime);
if (bounds.HasValue)
{
surface.size = bounds.Value.size;
surface.center = bounds.Value.center;
}
surface.BuildNavMesh();
Invoke(nameof(OnNavMeshBuilt), 1);
}
public virtual void OnNavMeshBuilt()
{
Debug.Log("NavigationBuilder - OnNavMeshBuilt");
NavMeshBuilt = true;
OnBuilt?.Invoke();
}
}
}
Still doesn’t work for me but I did some tests and am discovering that apparently it doesn’t like quad geometry? I’m playing around in the editor manually baking navmeshes and realizing that quads don’t seem to work but planes do. Doesn’t matter how large the quad is, it seems to be failing to sample it and I don’t see anything online about this being a problem for others.