Home > front end >  How can I detect when multiple rigid body velocities are under 0.1?
How can I detect when multiple rigid body velocities are under 0.1?

Time:10-30

I am developing an 8 ball pool/billiards game in which I want to find out when all the balls on the table stop.

I tried using this piece of code however the number of balls that have stopped keeps on incrementing to massive numbers when the value should be 16 or less.

    IEnumerator CheckObjectsHaveStopped()
    {
        bool allSleeping = false;
        Rigidbody[] GOS = FindObjectsOfType(typeof(Rigidbody)) as Rigidbody[];
        while (!allSleeping)
        {
            allSleeping = true;
            foreach (Rigidbody GO in GOS)
            {
                if (GO.velocity.magnitude <= 0.1)
                {
                    Balls_Stopped  = 1;
                    Debug.Log("Balls Stopped = "   Balls_Stopped);
                    yield return null;
                }
            }

        }

        if (Balls_Stopped == Balls_Left)
        {
            print("All objects sleeping");
            //Do something here
        }
    }

CodePudding user response:

Depending on your implementation requirements, it may be easier to treat each Ball as their own object. Then you can add a method/property to the Ball object such as "IsMoving".

I also recommend either serializing these ball objects in the inspector, or using FindObjectsOfType once at the beginning of your game so it is not impacting the performance of your game.

For example:

//Ball.cs

[RequireComponent(typeof(Rigidbody))]
public class Ball : MonoBehaviour {
    private Rigidbody rigidbody;

    public bool IsMoving => rigidbody.velocity.magnitude > 0.1f;

    private void Awake() {
        rigidbody = GetComponent<Rigidbody>();
    }
}

//Ball managing script
public class BallManagerScript : MonoBehaviour {
    private Ball[] balls;

    private void Awake() {
        balls = FindObjectsOfType<Ball>();
    }

    public bool CheckIfAnyBallsAreMoving() {
        foreach (Ball ball in balls) {
            if (ball.IsMoving) return true;
        }

        return false;
    }
}

This will allow you to have an array of Balls, which you can cycle through and check if each independent one is moving. From there, use that function to see if any of the balls are moving.

Make sure to add the Ball script to all balls in your game, so they can be referenced and checked.

using [RequireComponent(typeof(Rigidbody))]will ensure that each GameObject that Ball is attached too, will have a Rigidbody (because your script has a depdendency of Rigidbody)

CodePudding user response:

Using Linq you could do

using System.Linq;

...

var allStopped = GOS.All(r => r.velocity.magnitude <= 0.1f);
  • Related