# Get world position of random point inside bounds

I am trying to get a random world position inside my targets collider, so that I can fire an arrow at it.

I have tried a bunch of different solution but can't seem to get it right, for example (this code is on my target):

//Inside Awake
colliders = GetComponentsInChildren<Collider>(); //I want this to work on a unit with a single capsule collider and a building with 8 different box colliders

public Vector3 GetRandomPoint()
{
Bounds b = new Bounds();

for (int i = 0; i < colliders.Length; i++)
{
b.Encapsulate(colliders[i].bounds);
}

float minX = gameObject.transform.position.x - gameObject.transform.localScale.x * bounds.size.x * 0.5f;
float minZ = gameObject.transform.position.z - gameObject.transform.localScale.z * bounds.size.z * 0.5f;

return new Vector3(Random.Range (minX, -minX),
gameObject.transform.position.y,
Random.Range (minZ, -minZ));
}


In the scenario I'm having issues with right now, the trageet simply has a single capsule collider.

This return a point quite far away from my target, but I cant find the issue.

EDIT:

Here is another one I tried without success:

public Vector3 GetRandomPoint()
{
Bounds b = new Bounds();

for (int i = 0; i < colliders.Length; i++)
{
b.Encapsulate(colliders[i].bounds);
}

var target = new Vector3(
UnityEngine.Random.Range(b.min.x, b.max.x),
UnityEngine.Random.Range(b.min.y, b.max.y),
UnityEngine.Random.Range(b.min.z, b.max.z)
);

return b.ClosestPoint(target);
}

• What kind of a collide are you using, and where do you assign the bounds data? – DMGregory Sep 12 '20 at 12:49
• @DMGregory edited. – Majs Sep 12 '20 at 12:52
• Remember, new Bounds gives you a bounds that contains the world origin. Do you really want to encapsulate the world origin when your colliders are a long distance away from it? – DMGregory Sep 12 '20 at 12:55
• @DMGregory did not know that. No I dont. But how do I encapsulate colliders without creating new bounds? If a building has 8 different box colliders, I want to generate a random point inside any of these. – Majs Sep 12 '20 at 12:56
• Great! Want to write up your solution as an Answer below? – DMGregory Sep 12 '20 at 13:00

As instructed by @DMGregory, using new Bounds will use world origin, if I instead just use the first collider in the list, it works as intended:

public Vector3 GetRandomPoint()
{
Bounds b = colliders[0].bounds;

for (int i = 1; i < colliders.Length; i++)
{
b.Encapsulate(colliders[i].bounds);
}

var target = new Vector3(
UnityEngine.Random.Range(b.min.x, b.max.x),
UnityEngine.Random.Range(b.min.y, b.max.y),
UnityEngine.Random.Range(b.min.z, b.max.z)
);

return b.ClosestPoint(target);
}