- Home /
Random Movement of Enemy within a defined area
Hello!
I have some free roaming code for my enemy that works; the enemy walks around freely within the roamRadius. The problem is if you leave the enemy for a couple of minutes, he can have moved away really far from his original starting position.
I would like to set some boundaries on the enemy so he only moves within certain coordinates of the terrain and this is what I have today;
void FreeRoam()
{
{
Vector3 randomDirection = Random.insideUnitSphere * roamRadius;
randomDirection += transform.position;
NavMeshHit hit;
NavMesh.SamplePosition(randomDirection, out hit, roamRadius, 1);
Vector3 finalPosition = hit.position;
_nav.destination = finalPosition;
}
}
Anyone got any ideas how this could best be solved? I'm guessing the easiest way is perhaps to have a parenting game object with a Box Collider with Trigger and then using that as a reference point as to where the enemy can move inside?
I coded a similar behavior, with a boolean that lets me decide wehter the character may roam around freeley and end up god knows where, or be constrained to a certain area around his starting point.
Basically, when you have chosen a random Vector3 for the character to move towards, you add another check to see if the Vector3.Distance to the coordinates he starts from at game start (which you of course would have to save in a seperate variable in Start()) is equal to or less than a "stray radius" you want.
@Cherno I was about to write down the same solution, but this idea is not very delicate, because the script have to keep recalculate a new position and measure a new distance until it finds a valid point. This is perhaps not such a big issue for $$anonymous$$or games with few enemies, but if we are discussing large scale games, this is something that must be taken into account.
The smaller the distance of each random move action gets, the less iteration has to take place.
A better solution is no "Random" chance of finding a proper position.
Answer by Freaking-Pingo · Nov 02, 2013 at 07:19 PM
My best bet would be to first create a Vector3
that defines it start position, perhaps before it begins to roam. Then, whenever you create a new finalPosition
you make sure the start position and finalPosition
aren't exceeding some sort of distance threshold.
As an example you could basically just take this startPosition
and replace it with transform.position
so your code would look a little like this:
Vector3 startPosition;
void Awake()
{
startPosition = GetStartingPosition();
}
void FreeRoam()
{
{
Vector3 randomDirection = Random.insideUnitSphere * roamRadius;
randomDirection += startPosition;
NavMeshHit hit;
NavMesh.SamplePosition(randomDirection, out hit, roamRadius, 1);
Vector3 finalPosition = hit.position;
_nav.destination = finalPosition;
}
}
In this way, the new position is located in respect to the starPosition.
Answer by Zaeran · Nov 02, 2013 at 07:19 PM
You won't necessarily need a box collider. You can use a cube, and use 'renderer.bounds.Contains()' to determine if the next position is inside the area. If not, select a new position or rotate away.
ie.
if(!renderer.bounds.Contains(randomDirection + transform.position)){
randomDirection = -randomDirection; // if next point outside boundary, do a 180
}
randomDirection += transform.position;
Your answer
Follow this Question
Related Questions
Enemy moves randomly within a area. 1 Answer
2D Random AI 1 Answer
random direction of enemy when collide whit wall 1 Answer
Random Object Movement 0 Answers