-
-
Save IJEMIN/f2510a85b1aaf3517da1af7a6f9f1ed3 to your computer and use it in GitHub Desktop.
Considering this is the second result when googling around, I will leave my experiences here.
There are a few problems here.
- The
NavMesh#SamplePosition
returns a boolean. True if it found a point, false if not. This is not being checked. If the sampling fails, the code will break. Using the return value ofSamplePosition
in an if statement will remove the errors from that. Navmesh#SamplePosition
gets any position on the navmesh. If there are two disconnect areas and the sample distance is far enough, it will find a position on the navmesh which your agent might not be able to get to. See the image (sampling from camera position).
To get around the second problem, I would calculate the path before setting the destination to make sure it is reachable.
I have not tested this, but I'm sure you can figure something out along these lines.
bool foundPosition = NavMesh.SamplePosition(
origin + Random.insideUnitSphere * maxRange,
out navMeshHit,
maxRange,
NavMesh.AllAreas
);
if (!foundPosition)
// throw exception, return false, retry, some other way to handle failed sample
NavMeshPath path = new NavMeshPath();
this.navmeshAgent.CalculatePath(navMeshHit.position, path);
canReachPoint = path.status == NavMeshPathStatus.PathComplete;
Considering this is the second result when googling around, I will leave my experiences here.
There are a few problems here.
- The
NavMesh#SamplePosition
returns a boolean. True if it found a point, false if not. This is not being checked. If the sampling fails, the code will break. Using the return value ofSamplePosition
in an if statement will remove the errors from that.Navmesh#SamplePosition
gets any position on the navmesh. If there are two disconnect areas and the sample distance is far enough, it will find a position on the navmesh which your agent might not be able to get to. See the image (sampling from camera position).
To get around the second problem, I would calculate the path before setting the destination to make sure it is reachable. I have not tested this, but I'm sure you can figure something out along these lines.
bool foundPosition = NavMesh.SamplePosition( origin + Random.insideUnitSphere * maxRange, out navMeshHit, maxRange, NavMesh.AllAreas ); if (!foundPosition) // throw exception, return false, retry, some other way to handle failed sample NavMeshPath path = new NavMeshPath(); this.navmeshAgent.CalculatePath(navMeshHit.position, path); canReachPoint = path.status == NavMeshPathStatus.PathComplete;
thanks! :D I will update codes
If you don't mind having the "random" points in a grid, you can pregenerate points according to the navmesh's bounds and generate points using Mathf.PerlinNoise
Afterwards you can exclude all points that aren't found by NavMesh.SamplePosition and then choose a random valid point with Random.Range(0, pointList.Count)
Vector3 returning (infinity,infinity,infinity)