0
\$\begingroup\$

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);
    }
\$\endgroup\$
  • \$\begingroup\$ What kind of a collide are you using, and where do you assign the bounds data? \$\endgroup\$ – DMGregory Sep 12 '20 at 12:49
  • \$\begingroup\$ @DMGregory edited. \$\endgroup\$ – Majs Sep 12 '20 at 12:52
  • \$\begingroup\$ 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? \$\endgroup\$ – DMGregory Sep 12 '20 at 12:55
  • \$\begingroup\$ @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. \$\endgroup\$ – Majs Sep 12 '20 at 12:56
  • 1
    \$\begingroup\$ Great! Want to write up your solution as an Answer below? \$\endgroup\$ – DMGregory Sep 12 '20 at 13:00
1
\$\begingroup\$

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);
    }
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.