- Home /
Click to Move - get NavMesh Area Name
I'm creating a Click to move C# script, that use the built in Pathfinding using navmesh and NavMeshAgent.
My script currently works perfectly, but i want to do a important thing for the game i'm developing.
This is the current script that i have.
public bool CanMove = true;
private NavMeshAgent nav;
void Start(){
nav = GetComponent<NavMeshAgent>();
}
void Update () {
bool RMB = Input.GetMouseButtonDown(1);
bool reachedDestination = nav.remainingDistance <= float.Epsilon;
if(nav.isActiveAndEnabled && RMB && CanMove) {
RaycastHit hit;
Ray ray = Camera.main.ScreenPointToRay (Input.mousePosition);
if (Physics.Raycast (ray, out hit)) {
string tag = hit.transform.tag == null ? "NULL" : hit.transform.tag;
Debug.Log ("Hit: " + tag);
targetPosition = hit.point;
reachedDestination = false;
}
}
if(nav.isActiveAndEnabled && CanMove && !arrived && targetPosition != null){
nav.destination = targetPosition;
}
Using this, if i for example click on a Unwalkable
area of the terrain (a mountain for example), my characters move toward that point and stop on the maximum walkable area of the NavMesh.
What i need, is to check the Area of the NavMash, so if it is Walkable then i set the navMeshAgent.destination, else, i do nothing, or show a visual error that the character can't walk there.
Also, i need this because i will have multiple NavMesh Areas, for example, WalkableTerrain
, SwimableWater
, and so on.. and when the player try to move i need to know the area that he want to go.
So the question is, How i can modify my script to get the navMesh Area Name where the player Right Clicked?
Did you ever figure this out? I too would love to know how to get this at run-time. Looks like you can only retrieve the value with editor class GameObjectUtility.
Answer by Ash-Blue · Apr 17, 2016 at 07:18 AM
You cannot access this at run-time as of 5.3. You'll have to pre-cache and store the names somewhere via GameObjectUtility.GetNavMeshAreaNames() or reference the areas by ID. Horrible solution and hopefully this information is made available at run-time.
Answer by Happy-Zomby · Apr 17, 2016 at 08:13 AM
Hi, you can use sample position to get the mask http://docs.unity3d.com/ScriptReference/NavMesh.GetAreaFromName.html
If you do a first classic raycast - you can then use that hit point to do your sample position
if(NavMesh.SamplePosition(physicsHit.point, out navmeshHit, 1.0f))
and then use
navmeshHit.mask
When I use that with agent.sampleposition - I got power of 2 results but I was able top work with that
switch (navHit.mask) //check area mask and change speed in function
{
case 8:
agent.speed = 7/mod;
break;
case 16:
agent.speed = 6/mod;
break;
case 32:
agent.speed = 5/mod;
break;
case 64:
agent.speed = 3/mod;
break;
case 128:
agent.speed = 0.5/mod;
break;
}
hope that helps
Raycasts are fairly expensive although you could cache the response. On the other hand comparing against potentially changing IDs is incredibly error prone. If it was comparing against string names this could be a really great solution. As mentioned in my post though, the corresponding names for the IDs are locked away in the editor unless you post-process them into a cache.