How to check if an object has stopped moving?

Hey guys,

I have an object, with a rigidbody on it. I have it as the player. I want to be able to check exactly when the object has stopped moving. By this I don’t mean completely stop moving because that would take a very long time and it isn’t precise.

How would I go about checking if the object has almost stopped moving completely?

Also, how would I make it that when the rigidbody has almost completely stopped, the script then forcibly completely freezes the character?

float speed;
void Update () {
speed = rigidbody.velocity.magnitude;
if(speed < 0.5) {
gameObject.rigidbody.velocity = new Vector3(0, 0, 0);
//Or
gameObject.rigidbody.constraints = RigidbodyConstraints.FreezeAll;
}
}

I kind of took this question to heart and coded it up for you. You essentially want to store a few of the previous positions of the object and check if the distance between any of those positions is really small. Hopefully the comments and the code explain it better than me.

//Set this to the transform you want to check
private Transform objectTransfom;

private float noMovementThreshold = 0.0001f;
private const int noMovementFrames = 3;
Vector3[] previousLocations = new Vector3[noMovementFrames];
private bool isMoving;

//Let other scripts see if the object is moving
public bool IsMoving
{
	get{ return isMoving; }
}

void Awake()
{
	//For good measure, set the previous locations
	for(int i = 0; i < previousLocations.Length; i++)
	{
		previousLocations *= Vector3.zero;*
  • }*
    }

void Update()
{

  • //Store the newest vector at the end of the list of vectors*
  • for(int i = 0; i < previousLocations.Length - 1; i++)*
  • {*
    _ previousLocations = previousLocations[i+1];_
    * }*
    * previousLocations[previousLocations.Length - 1] = objectTransfom.position;*

* //Check the distances between the points in your previous locations*
* //If for the past several updates, there are no movements smaller than the threshold,*
* //you can most likely assume that the object is not moving*
* for(int i = 0; i < previousLocations.Length - 1; i++)*
* {*
_ if(Vector3.Distance(previousLocations*, previousLocations[i + 1]) >= noMovementThreshold)
{
//The minimum movement has been detected between frames*
* isMoving = true;
break;
}
else*
* {
isMoving = false;
}
}
}*_

In my game I use Rigidbody’s sleep property. Once a rigidbody is not being acted upon it will sleep, and this indicates it is not moving:

A little late to the party here. Andy’s answer works well for checking using transform. Lylek’s answer works well for gameobjects with rigid bodies. I have another solution similar to Andy’s for those who would like a smaller code example.

	private bool isBeingMoved;
	private Vector3 priorFrameTransform;
	public Transform lens;

	bool IsBeingMoved {
		get { return this.isBeingMoved; }

		set {

            if (this.isBeingMoved && !value)
                // Transformation has stopped
            this.isBeingMoved = value; 
		}
	}

	// Use this for initialization
	void Start () {
		IsBeingMoved = false;
		priorFrameTransform = transform.position;
	}
	
	// Update is called once per frame
	void Update () {

		if (Vector3.Distance(transform.position, priorFrameTransform) > 0.01f ) {
			IsBeingMoved = true;
		} else {
            if (IsBeingMoved)
			    IsBeingMoved = false;
		}

		priorFrameTransform = transform.position;
	}

May be this one line of code solves your issue. This works in my case.

I also tried rigidbody.IsSleeping() in my case but it was not returning true even when vehicle was nearly stopped. Maybe because the vehicle was always moving a very little amount let say 0.0001 units to and from because its engine were started so in my case, this solved the issue.

if(rigidbody.transform.InverseTransformDirection(rigidbody.velocity).z < 0.1f && rigidbody.transform.InverseTransformDirection(rigidbody.velocity).z > -0.1f)
    {
    print("rigid body is nearly stationary.")
    }

This detects basically if the vehicle is moving ahead of backward with respect to its own axis instead of detected velociy with respect to global axis. So if vehicle has negligible movement with respect to own forward axis, then it is nearly static.