News › Forums › Troubleshooting › How to check point is on the nav mesh?
Tagged: nav mesh crash
This topic contains 22 replies, has 4 voices, and was last updated by abchiptop 9 months ago.
-
AuthorPosts
-
February 23, 2022 at 1:36 pm #8272
I used the following script to create a wander location similar to that described in the wander tutorial but having to add an extra float to the OnGraph method.
However the an.Navigator.OnGraph(loc, 0f);
part doesn’t function as I expect.
I thought this would only return true if the location was on the nav mesh however I seem to be getting locations way off it.
My script creates a cube at the location for visualization purposes.
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Core; using RAIN.Action; [RAINAction("Choose Wander Location")] public class AIChooseWanderLocation : RAINAction { public AIChooseWanderLocation() { actionName = "AIChooseWanderLocation"; } public override void Start(AI ai) { base.Start(ai); } public override ActionResult Execute(AI ai) { Vector3 loc = Vector3.zero; do { loc = new Vector3(Mathf.Clamp(ai.Kinematic.Position.x + Random.Range(-15f, 15f), -25f, 25f), ai.Kinematic.Position.y, Mathf.Clamp(ai.Kinematic.Position.z + Random.Range(-15f, 15f), -25f, 25f)); } while ((Vector3.Distance(ai.Kinematic.Position, loc) < 5f) || !ai.Navigator.OnGraph(loc,0f)); ai.WorkingMemory.SetItem<Vector3> ("wanderTarget", loc); // create cube at position GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube); //cube.AddComponent<Rigidbody>(); cube.transform.position = loc; return ActionResult.SUCCESS; } public override void Stop(AI ai) { base.Stop(ai); } }
Is there a better way to check the point is reachable? additionally the mesh has generated some unconnected nav mesh regions that it is possible this point would appear on… however my character wouldn’t be able to get to them. Is there a way to check if the point is reachable rather than just checking if it is “on the nav mesh”.
February 24, 2022 at 7:48 pm #8351Its a bit of an odd one this, it seems that the AI doesn’t start with a Navigation Mesh attached and doesn’t pick it up for a few cycles which means OnGraph will always return true with no NavMesh.
To fix the problem add this line to your Start() function in your action….
I’m lazy and am testing so my navigation mesh is called “Navigation Mesh” i’d assume yours is possibly the same!
public override void Start(AI ai)
{
base.Start(ai);
ai.Navigator.CurrentGraph = NavigationManager.instance.GetNavigationGraph (“Navigation Mesh”);}
Your cubes should now appear on the graph all the time!
Good Luck
Marc
February 25, 2022 at 1:09 am #8398RAIN 2.0.10 should automatically grab a navmesh on start - you don’t need to add that code anymore.
The code you are using is from the first tutorial I put together - and I’m wishing I had put more thought into it before i posted the code. It isn’t the best implementation.
1) Get rid of the Clamp functions. They are just going to cause problems
2) Instead of OnGraph, you should checkNavigationManager.instance.GetGraphsForPoints(ai.Kinematic.Position, loc, ai.Motor.StepUpHeight, GraphType.NavMesh, ((BasicNavigate)ai.Navigator).GraphTags).Count > 0
February 25, 2022 at 1:17 am #8403Not that i’m chasing you about the forums here Prime but I think I better stop answering questions, thats two for two I was wrong on!
Although I would say Debug.Log(ai.Navigator.CurrentGraph) right after base.Start(ai) was showing Null this afternoon for me which is why I came round to that solution which I found elsewhere on the forum. I’m definitely on the latest version of rain.
February 25, 2022 at 1:42 am #8413The graph isn’t necessarily non-null immediately. However, there is a new check on the Navigator to force a refresh of the mesh before allowing any pathfinding functions to run. So it would happen right before the first Move call or the first OnGraph check, for example.
February 25, 2022 at 10:29 am #8445Hello,
I replaced the while condition to :
while ((Vector3.Distance(ai.Kinematic.Position, loc) < 5f) || (NavigationManager.instance.GetGraphsForPoints(ai.Kinematic.Position, loc, ai.Motor.StepUpHeight, GraphType.NavMesh, ((BasicNavigate)ai.Navigator).GraphTags).Count > 0));
As suggested but the compiler can’t find NavigationManager.
Any ideas ?
EDIT:
I added using RAIN.Navigation; to the top of the script. it finds the NavigationManager but doesn’t have a .instance.GetGraphsForPoints member?
- This reply was modified 9 months, 4 weeks ago by zcoldrick.
February 25, 2022 at 11:21 am #8449I have the same issue, just messing around with it now, I can’t see a GetGraphsForPoints method in the documentation, there is however a GraphsForPoints. Give me 20 and i’ll post back, again i’m no expert but we happen to be working on the same thing!
February 25, 2022 at 11:55 am #8452Yeah i’m not even going to make a suggestion on that, will wait for Prime to get back.
February 25, 2022 at 2:42 pm #8471You need a using statement.
using RAIN.Navigation;
February 25, 2022 at 2:51 pm #8474I have that already…
Code is as follows:
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Core; using RAIN.Action; using RAIN.Navigation; [RAINAction] public class ChoseWanderLocation : RAINAction { public ChoseWanderLocation() { actionName = "ChoseWanderLocation"; } public override void Start(AI ai) { base.Start(ai); //ai.Navigator.CurrentGraph = NavigationManager.instance.GetNavigationGraph ("Navigation Mesh"); } public override ActionResult Execute(AI ai) { Vector3 loc = Vector3.zero; do { loc = Vector3.zero; loc = new Vector3(Mathf.Clamp(ai.Kinematic.Position.x * Random.Range (-20f,20f),-30f,30f), ai.Kinematic.Position.y, Mathf.Clamp(ai.Kinematic.Position.z * Random.Range (-20f,20f),-30f,30f)); } while ((Vector3.Distance(ai.Kinematic.Position, loc) < 5f) || (NavigationManager.instance.GetGraphsForPoints(ai.Kinematic.Position, loc, ai.Motor.StepUpHeight, GraphType.NavMesh, ((BasicNavigate)ai.Navigator).GraphTags).Count > 0)); //while ((Vector3.Distance (ai.Kinematic.Position , loc) < 5f)|| !ai.Navigator.OnGraph(loc,0f)); ai.WorkingMemory.SetItem<Vector3> ("wanderTarget", loc); return ActionResult.SUCCESS; }
Error thats given:
Assets/AI/Actions/ChoseWanderLocation.cs(36,109): error CS1061: Type RAIN.Navigation.NavigationManager does not contain a definition for GetGraphsForPoints and no extension method GetGraphsForPoints of type RAIN.Navigation.NavigationManager could be found (are you missing a using directive or an assembly reference?)
If I change GetGraphsForPoints for GraphsForPoints I then get:
1)Assets/AI/Actions/ChoseWanderLocation.cs(36,176): error CS0103: The name GraphType does not exist in the current context
2)
Assets/AI/Actions/ChoseWanderLocation.cs(36,197): error CS0246: The type or namespace name BasicNavigate could not be found. Are you missing a using directive or an assembly reference?
3)
Assets/AI/Actions/ChoseWanderLocation.cs(36,109): error CS1502: The best overloaded method match for
RAIN.Navigation.NavigationManager.GraphsForPoints(UnityEngine.Vector3, UnityEngine.Vector3, float, RAIN.Navigation.NavigationManager.GraphType, System.Collections.Generic.List<string>)’ has some invalid arguments
4)
Assets/AI/Actions/ChoseWanderLocation.cs(36,109): error CS1503: Argument #4 cannot convert object expression to type RAIN.Navigation.NavigationManager.GraphType
`- This reply was modified 9 months, 4 weeks ago by marcfielding.
- This reply was modified 9 months, 4 weeks ago by marcfielding.
- This reply was modified 9 months, 4 weeks ago by marcfielding. Reason: trying to sort formatting from unity error console
- This reply was modified 9 months, 4 weeks ago by marcfielding.
- This reply was modified 9 months, 4 weeks ago by marcfielding.
February 25, 2022 at 3:51 pm #8486The code should be
NavigationManager.instance.GraphsForPoints
The “GetGraphsForPoints” is a typo.
- This reply was modified 9 months, 4 weeks ago by prime.
February 25, 2022 at 4:21 pm #8491Hi Prime,
I appreciate your really busy and probably flying through these but I said in my post I made that swap, theres a list of after that!
Thanks
Marc
February 25, 2022 at 5:18 pm #8499Hmm. Too many typos.
“BasicNavigate” should be BasicNavigator.
GraphType should be NavigationManager.GraphType
February 25, 2022 at 6:55 pm #8507The following scripts works, until the object target appears under a create (using the mechanim tutorial green crate scene).
When this happens the character walks up to it and either stops or the game crashes.
Until that happens, the character walks from target to new target quite happily.
using UnityEngine; using System.Collections; using System.Collections.Generic; using RAIN.Core; using RAIN.Action; using RAIN.Navigation; [RAINAction("Choose Wander Location")] public class AIChooseWanderLocation : RAINAction { // add in a cube and rename Indicator to display target location private GameObject Indicator; public AIChooseWanderLocation() { actionName = "AIChooseWanderLocation"; } public override void Start(AI ai) { base.Start(ai); Indicator = GameObject.Find ("Indicator"); } public override ActionResult Execute(AI ai) { Vector3 loc = Vector3.zero; do { loc = new Vector3(ai.Kinematic.Position.x + Random.Range(-8f, 8f), ai.Kinematic.Position.y, ai.Kinematic.Position.z + Random.Range(-8f, 8f)); } while ((Vector3.Distance(ai.Kinematic.Position, loc) < 5f) || !(NavigationManager.instance.GraphsForPoints(ai.Kinematic.Position, loc, ai.Motor.StepUpHeight, NavigationManager.GraphType.Navmesh, ((BasicNavigator)ai.Navigator).GraphTags).Count > 0 )); //if CharacterStepUpHeight is set correctly you that in graphsforpoints third parameter instead of 0f ai.WorkingMemory.SetItem<Vector3> ("wanderTarget", loc); // create cube at position Indicator.transform.position = loc; return ActionResult.SUCCESS; } public override void Stop(AI ai) { base.Stop(ai); } }
February 26, 2022 at 12:05 pm #8551The previous code only works for a short time because I’m ‘Inverting’ the output of :
(NavigationManager.instance.GraphsForPoints(ai.Kinematic.Position, loc, ai.Motor.StepUpHeight, NavigationManager.GraphType.Navmesh, ((BasicNavigator)ai.Navigator).GraphTags).Count > 0 )
When this returns true unity crashes.
This clearly isn’t the function my droids are looking for.
Ideally I just want a function such like:
isOnMesh(Vector3 transform, bool ignoreY)
which would return true if the point was on the mesh or false if not, the ignore y would allow it to just check the x and z coordinates so that height issues with the initial object were ignored.
OR:
isValidPath(Vector3 transform1, Vector3 transform2, float setupheight, (unknown type) navmesh, (unknown type) ignoreTags)
Ideally this should return true if a valid path exists between transform1 and transform2 and false if not.
This last one would be similar to that function GraphsForPoints() but have a more obvious return type. I can’t work out what the return type for it is and the .count member variable isn’t obvious to me.
-
AuthorPosts
You must be logged in to reply to this topic.