Wednesday 29 February 2012

Unity: Calculate Velocity of non-rigidbodies


Say you need to calculate the velocity of a gameobject in motion and you can't or dont want to put a rigidbody on it. Whats the easiest way to do it?
Here's how I calculate velocity using co-routines:


void Start ()
{
  StartCoroutine( CalcVelocity() );
}
 
IEnumerator CalcVelocity()
{
  while( Application.isPlaying )
  {
    // Position at frame start
    prevPos = transform.position;
    // Wait till it the end of the frame
    yield return new WaitForEndOfFrame();
    // Calculate velocity: Velocity = DeltaPosition / DeltaTime
    currVel = (prevPos - transform.position) / Time.deltaTime;
    Debug.Log( currVel );
  }
}

To test it out, attach it to a moving game object. Very simple and straightforward, but can be used in a lot of places.

15 comments:

  1. Very Clean Results !! thanks for this

    ReplyDelete
  2. Why do you use a co-routines here, instead of just updating your position variables in the update loop and calling a calcVelocity function whenever you need to return the velocity?

    ReplyDelete
  3. doesnt work anymore on unity 5.1.1

    ReplyDelete
    Replies
    1. Make sure you know how to edit your script as needed for your game. Because if you just simply copy and paste this to that without knowing whats wrong, then youre not gonna get pretty far in development.

      Delete
  4. IEnumerator CalcVelocity()
    {
    while( Application.isPlaying )
    {
    // Position at frame start
    Vector3 prevPos = player.transform.position;
    // Wait till the end of the frame
    yield return new WaitForEndOfFrame();
    grenadeVariables.currentPlayerVelocity = (prevPos - player.transform.position) / Time.deltaTime;
    //Debug.Log( grenadeSettings.currentPlayerVelocity );
    }
    }

    ReplyDelete
  5. This comment has been removed by the author.

    ReplyDelete
  6. Thank you works great! Before using Rigidbody.magnitude I was only getting results with gravity turned on, on the Rigidbody. Not always the case in my game!

    I also StopCourotine when speed hits zero an plan on starting it again when hit by another object! If you want to use this approach though and apply it to a falling object you need some kind of boolean in update because when your object first instantiates its at 0 velocity! I just made the boolean true basically after the speed was over x amount in the Enumerator!

    ReplyDelete
  7. It works better than just throwing the code in Update, but the speed still keeps fluctuating, there isn't a smooth transition between values (I'm using the Vector3 magnitude value). I tried with 2 objects, one that follows the cursor and another one (with rigidobdy) that slowly moves towards the cursor. The behaviour is the same with both.

    ReplyDelete
    Replies
    1. You can possibly add a lerp so the speed spikes wont be as bad. Or you can get complex and make custom acceleration script/s.

      Delete
  8. Finally, I have been poking around looking for this for 7 hours. All I keep seeing is rigidbody.velocity. Velocity does even exist in my program! Thank you.

    ReplyDelete
  9. This was also how I wanted to do mine, but I couldnt get the delay right to get 2 positions. Thanks man

    ReplyDelete
  10. void Start()
    {
    StartCoroutine(CalcVelocity());
    }

    IEnumerator CalcVelocity()
    {
    while (Application.isPlaying)
    {
    var prevPos = transform.position;
    yield return new WaitForEndOfFrame();
    var currVel = (prevPos - transform.position).magnitude / Time.deltaTime;
    Debug.Log(currVel);
    }
    }

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. The velocity result will be in meters per second? What are the units of the velocity variable?

    ReplyDelete
  13. I found your this post while searching for information about blog-related research ... It's a good post .. keep posting and updating information. velocity calculator

    ReplyDelete

Contributors

Followers