3
\$\begingroup\$

I am trying to create a "wander" action that will make my NPC walk to a random position.

The catch is that the NPC should only go positions inside of a collider.

I have a huge Sphere that has a collider on it now I only want my NPC to go to positions that are inside that Sphere collider.

My question is how do i find a random position inside of a colider?

Update

So after testing i am unable to use colliders because the sphere is too big here is an image of my gameobject:

enter image description here

As you can see from the image I have a huge sphere that my NPC's will have to stay inside when wandering

In order to use the Collider.ClosestPoint() the collider has to be a Box, sphere or a mesh collider with a convex.

Sadly this is not feasible for me because the sphere should not collide with other objects.

So my question is how do I find a point inside this gameobject?

\$\endgroup\$

2 Answers 2

4
\$\begingroup\$

Use Collider.ClosestPoint(Vector3 position). From the documentation:

Returns a point on the collider that is closest to a given location.

Update:

Sadly this is not feasible for me because the sphere should not collide with other objects.

If you want your collider to not limit movement of objects, you can turn it into a Trigger. The function Collider.ClosestPoint can be used regardless.

Here's some example:

class MyNPC {

    // Assign through inspector
    public Collider bigSphere;

    // Where to move to
    Vector3 target;

    // Called when NPC has to select a new location to move to
    void SelectTarget() {

        // Bounds of the sphere
        Bounds b = bigSphere.bounds;

        // Get a random point inside the bounds
        target = new Vector3(
            Random.Range( b.min.x, b.max.x ),
            Random.Range( b.min.y, b.max.y ),
            Random.Range( b.min.z, b.max.z )
        );

        // Find the closest point that belongs in the collider from that
        target = bigSphere.ClosestPoint(target);

        // Now target holds a random point inside the sphere

    }
\$\endgroup\$
2
  • \$\begingroup\$ Hey sadly my sphere was too big to be able to use colliders i am updating my questions please have a look in a few minutes \$\endgroup\$ Commented Apr 13, 2018 at 10:21
  • \$\begingroup\$ @MarcRasmussen I updated my answer \$\endgroup\$ Commented Apr 13, 2018 at 10:41
0
\$\begingroup\$

Why not do some maths?

To generate a point which is inside said sphere, just make sure the distance from the sphere's origin (center) to the random generated point is lower than the sphere's radius. (you can work the calculation out with the squared distance since you don't need the actual difference - to optimize calculations speed)

To reduce the number of randomly generated coordinate tuples which don't satisfy the condition above, make it so that your random function generates numbers between 0 and your sphere's radius. Then there is a great chance that the resulting 3d point will be inside - if not then generate another one etc.

\$\endgroup\$
3
  • \$\begingroup\$ could you give a code example of how this may work+ \$\endgroup\$ Commented Apr 13, 2018 at 11:03
  • \$\begingroup\$ No, I don't regularly use Unity3d - you figure it out! It's really simple. Say x, y, z are your point's coordinates and sx, sy, sz are the sphere center coordinates; r is the sphere radius. Then the condition to be satisfied is the following: (sx-x)^2 + (sy-y)^2 + (sz-z)^2 < r^2 Also, don't forget that if you generate coordinates in the [0,r) interval, they need to be translated relative to the sphere center position before applying the above. \$\endgroup\$
    – octo
    Commented Apr 13, 2018 at 11:15
  • 1
    \$\begingroup\$ In Unity you can do this with pointInSphere = sphereCenter + Random.insideUnitSphere * sphereRadius; \$\endgroup\$
    – DMGregory
    Commented Apr 13, 2018 at 11:53

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .