- Home /
Get a random point in an arc within a specified min/max distance
I'm programming a gameobject to move across a field towards a waypoint via NavMeshAgent, but wish to make it that so that the gameobject won't move in a straight line towards the point in a single sitting. I'm looking to have it set that it'll only move a certain min/max distance at a time, and within an arc that faces the point, and repeat the process until it reaches the point. I have the interval workings set up, so I only wish for help about getting a new point for each one.
Here's the gist of it: 1: Get two vectors on the field 2: Generate an arc (let's say 90 degrees) from the first vector that faces towards the second vector 3: get a random point within the arc that stays within the limits of a minimum and maximum distance from the first vector (say, 20 and 40, respectively)
C# is preferred, but I have no issues with answers written in Javascript. Any suggestions are appreciated. Thank you!
Here is the code I tried making to achieve this. The problem with this code, above being rather all over the place, is that when too many units running this script are present on the field, Unity suffers a memory error and freezes.
//Get the vectors of the tank and the target destination,
Vector3 pos = transform.position;
Vector3 dest = currentDestination.transform.position;
float rnd = Random.Range(travelDistMin,travelDistMax);
//Make a new point that's towards the target destination between the tank's min and max travel distance
Vector3 newPos = Vector3.MoveTowards(pos, dest, rnd);
bool found = false;
while (found == false)
{
//Establish a random point within a radius
Vector3 randomDirection = Random.insideUnitSphere * (travelDistMax);
//Add the random point's offset to the new position
randomDirection += newPos;
//Ensure randomDirection is within a narrow angle from pos and newPos
if(Vector3.Angle(randomDirection - pos, newPos - pos) < 90)
{
//Translate the position onto a valid spot in the NavMesh
NavMeshHit hit;
NavMesh.SamplePosition(randomDirection, out hit, 20, 1);
//Set the final position to the new position + the offet to an elevation on the NavMesh
Vector3 finalPosition = hit.position;
//destinate the final position, reset the stopping distance to the standard value, and change the AI state
brain.destination = finalPosition;
brain.stoppingDistance = standardStoppingDistance;
currentState = AIStates.Moving;
found = true;
}
}
Answer by robertbu · Nov 24, 2013 at 04:25 PM
Without more info, I have to guess a bit. The code will look something like (untested):
function GenerateNewVector() : Vector3 {
var v3 = target.pos - transform.position;
v3.y = 0.0;
dist = v3.magnitude;
if (dist > minDist) {
v3 = Quaternion.AngleAxis(0.0, Ransom.Range(-maxAngle, maxAngle), 0.0) * v3;
v3 = v3.normalized * Random.Range(minDist, Mathf.Min(maxDist, dist));
}
return v3;
}
Note maxAngle is the maximum angle you want with respect to perfect aim.
I added some more info to the question. Hope this helps. Thank you for your contributions!