- Home /
Programmatically specifying a random point in an arc in front of the player
I'm trying to get NPCs to consistently spawn in front of the PC, and to this end I'm trying to randomly select a point in an arc in front of the PC. To that end, I've been doing this:
Vector3 RandomPointInCircle(Vector3 center, float radius, float angle){ //Draws circle of radius, with center center, and locates a point on that circle within angle angle
Vector3 position;
position.x = center.x + radius * Mathf.Sin (angle * Mathf.Deg2Rad);
position.y = center.y + radius * Mathf.Cos (angle * Mathf.Deg2Rad);
position .z = center.z;
return position;
}
I thought that passing it the player's position, a radius of 5, and an angle of Random.range(45, -45) would result in enemies spawning at random points within a 90 degree arc in front of the player, but every enemy spawns at the same point, to the player's right- is my math slightly borked?
Haven't looked at the math. But one quick way to tell if you math is off would be to write a loop that passes in angles from -45 to 45, say five apart, and makes a cube at those positions. Then you can at least check if its this method or your random generator that's misbehaving.
For polar to rect, you have your sin and cos backwards. It cos for x and sin for y...but this is likely not your problem since the results would not be the 'same point'.
Answer by Bunny83 · Nov 23, 2014 at 02:38 AM
Your code should work just fine, however keep in mind that when in 3D the y-axis is up. So since your arc is on the x-y plane, the point will be displaced on the x axis and the y-axis. If you want a point on the x-z-plane you should use z and not y in your code.
Also keep in mind that you work in worldspace and not relative to a certain object. (just saying since you said "in front of the player")
edit
To specify a point in localspave you either have to write your method a bit more general and then use the Transform's TransformPoint method, or directly use the transforms local axis in the calculation:
Vector3 RandomPointInCircle(float radius, float angle){
float rad = angle * Mathf.Deg2Rad;
Vector3 position = new Vector3(Mathf.Sin( rad ), 0, Mathf.Cos( rad ));
return position * radius;
}
// Now use like this:
var localPoint = RandomPointInCircle(5,angle);
var worldPoint = transform.TransformPoint(localPoint);
The other way would be to pass a Transform reference to the method and use it like this:
Vector3 RandomPointInCircle(Transform trans, float radius, float angle){
float rad = angle * Mathf.Deg2Rad;
Vector3 position = trans.right * Mathf.Sin( rad ) + trans.forward * Mathf.Cos( rad );
return trans.position + position * radius;
}
Oooh, that explains so much- thank you! :)
Is there a way to specify local space, or would I need to do my calculation normally than adjust it for my PC.forward?
Thank you so much, I really appreciate your help :)