Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by stevensu1838 · Jun 03, 2019 at 01:29 AM · rigidbodytransformvelocitytransform.position

Two ways to calculate velocity without using Rigidbody, which one is more accurate?

Hi all,

I've learn't two ways to calculate velocity of a 3D game object without using Rigidbody, which are shown below. I attached the two scripts onto a same object (a cube) and I've noticed the velocity outcomes of the two methods at the same moment are not exactly the same. Can you please tell me which one can represent the velocity more precisely? And can you please tell me why the two scripts work differently? Thanks a million.

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class VelocityReader : MonoBehaviour
 {
     public Vector3 linearVelocity;
     private float previousRealTime;
 
     //private GeometryTwist message;
     private Vector3 previousPosition = Vector3.zero;
     private Quaternion previousRotation = Quaternion.identity;
     // Start is called before the first frame update
     void Start()
     {
         
     }
 
     // Update is called once per frame
     void Update()
     {
         float deltaTime = Time.realtimeSinceStartup - previousRealTime;
         linearVelocity = (transform.position - previousPosition) / deltaTime;
         Vector3 angularVelocity = (transform.rotation.eulerAngles - previousRotation.eulerAngles) / deltaTime;
         Debug.Log("Vlinear" + linearVelocity);
         previousRealTime = Time.realtimeSinceStartup;
         previousPosition = transform.position;
         previousRotation = transform.rotation;
     }
 }

And the second script is:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;
 
 public class ObjVelocityReader : MonoBehaviour
 {
     Vector3 PrevPos;
     Vector3 NewPos;
 
     Vector3 PrevRot;
     Vector3 NewRot;
 
     public Vector3 ObjVelocity;
     public Vector3 ObjRotation;
     // Use this for initialization
     void Start()
     {
         PrevPos = transform.position;
         PrevRot = transform.eulerAngles;
     }
 
     // Update is called once per frame
     void FixedUpdate()
     {
         transform.rotation = Quaternion.identity;
 
         NewPos = transform.position;  // each frame track the new position
         ObjVelocity = (NewPos - PrevPos) / Time.fixedDeltaTime;
         PrevPos = NewPos;  // update position for next frame calculation
         Debug.Log("ObjVlinear" + ObjVelocity);
 
         NewRot = transform.eulerAngles;  // each frame track the new rotation
         ObjRotation = (NewRot - PrevRot) / Time.fixedDeltaTime;
         PrevRot = NewRot;  // update position for next frame calculation
     }
 }


Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

1 Reply

· Add your reply
  • Sort: 
avatar image
2

Answer by highpockets · Jun 03, 2019 at 08:09 AM

Ok, a few things are a bit off here. In the first script, you are calculating the delta time like this Time.realtimeSinceStartup - previousRealTime;, but a variable already exists in the Time class that has that ready for you. It's called deltaTime Time.deltaTime; is all you need, no need to recalculate it. Secondly, the second script is using fixedDeltaTime which is always the same number, whatever you have set in the project settings of unity ( 0.02f is the default I believe ), so you should use Time.deltaTime there as well. Also, you will be getting the readings at different times, because one is calculating in the physics loop (FixedUpdate()) and one is calculating every frame (Update()). But I think the real game changer here is the use of fixedDeltaTime. Take a look at the documentation:


https://docs.unity3d.com/ScriptReference/Time-fixedDeltaTime.html


For reading the delta time it is recommended to use Time.deltaTime instead because it automatically returns the right delta time if you are inside a FixedUpdate function or Update function.

Comment
Add comment · Show 13 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image stevensu1838 · Jun 03, 2019 at 09:50 AM 0
Share

Hi highpockets, Thanks a lot for your reply. Do you think I should use Update() or FixedUpdate() in the two scripts above? And in the first script previousPosition is declared and assigned Zero below the class definition. However in the second script PrevPos is declared in the start() function but not assigned Zero as shown below. Is there any difference? Thanks a million. 1.

  public class VelocityReader : $$anonymous$$onoBehaviour
  {
      public Vector3 linearVelocity;
      private float previousRealTime;
      private Vector3 previousPosition = Vector3.zero;
      private Quaternion previousRotation = Quaternion.identity;

2.

  void Start()
      {
          PrevPos = transform.position;
          PrevRot = transform.eulerAngles;



avatar image highpockets stevensu1838 · Jun 03, 2019 at 10:00 AM 0
Share

FixedUpdate is generally considered the best place to calculate physics and that is what you are doing here, so I would say FixedUpdate() to be safe. It would be best to declare and assign previousPosition in the Start() method like the second script because assigning it (0,0,0) is not correct unless the object is at the world origin at the start. Assigning transform.position to it in the start method will always start with the correct position regardless of the start position of the object in question

avatar image Bunny83 · Jun 03, 2019 at 09:54 AM 0
Share

Note that when you read Time.deltaTime inside FixedUpdate it will actually return the value of Time.fixedDeltaTime. So it makes no difference inside FixedUpdate. That's why it's recommended to use deltaTime all the time because you can easily use the same code elsewhere without any changes.


Whether or not one should use Update or FixedUpdate depends on how and where the object is actually moved. If it's moved in FixedUpdate, using FixedUpdate will be more accurate. Though the better results you get when moving the object in Update if you are not using the physics system.


Though the question to "measure" the velocity is rather strange to begin with. Since no physics are involved an object doesn't move on its own. So there has to be some code that actually moves the object (unless it's animation driven). In that case the code that moves the object already knows the velocity.


For example the eulerAngles calculations can give you funky results when the angles wrap around. There is no accurate way to deter$$anonymous$$e the angular velocity just from looking at two snapshots. This is know as the wagon wheel effect. If you measure a certain speed it could be v but also any v-+(360*i) for any integer "i". So if you measure say -10 degree per second on the y axis, it could also be 350°/s or -370°/s or 2510°/s

avatar image highpockets Bunny83 · Jun 03, 2019 at 10:14 AM 0
Share

Oops ya, that’s right so the game changer is not fixedDeltaTime as FixedUpdate is always calculating at that set interval.. I’m once again corrected by @Bunny83 haha, cheers

avatar image stevensu1838 highpockets · Jun 03, 2019 at 01:32 PM 0
Share

Hi highpockets, @highpockets Can you please also take a look at my explanation to my application? Thanks a lot for your constant support. Cheers.

Show more comments
avatar image stevensu1838 Bunny83 · Jun 03, 2019 at 01:30 PM 0
Share

Hi Bunny83, @Bunny83 Thank you so much for your explanation. So from your point of view, the second script mostly does the work.And I'd like to tell you what I am doing. I am grabbing and moving a cube object in unity with either Leap$$anonymous$$otion sensor or the HTC vive controller and I want to learn about the velocity of this cube that I am moving in order to use this data to move something else.What's more, I also want to save this same velocity data of the cube into a CSV file in order to reply the whole movement of the cube when I am not grabbing it at all(by saying reply I mean read the velocity data I saved while grabbing and moving a cube then the cube or some other object can repeat the whole movement of the cube moved by Leap$$anonymous$$otion or HTC vive). Does this make any sense to you?

Honestly, I am not sure at all if my idea can be done with getComponent().Velocity through rigidbody. What do you think? The reason why I tried to calculate the velocity of the cube is simply I could drag the cube to move in the scene in unity without using the Leap $$anonymous$$otion or Vive Controller to check if I can obtain the speed or not. By saying this I mean if you drag the cube to move in the scene in unity without using the Leap $$anonymous$$otion or Vive Controller to check the rigid body velocity, it always returns 0. Because I never accessed the rigidbody component i.e add force to it, all I did was simply change the object's location based on mouse input.

$$anonymous$$orrow I would put in my Leap $$anonymous$$otion or HTC vive controller and add rigidbody to the cube to check if I can get the rigid body velocity of the cube. According to your expertise, do you think I can use rigid body velocity for my application. What is the best way? Thanks a lot.

avatar image stevensu1838 Bunny83 · Jun 05, 2019 at 12:56 PM 0
Share

@Bunny83 Hi, One more questions about the two scripts above. When it come to the calculation of angular speed, the fist script uses transform.rotation.eulerAngles but transform.eulerAngles is used in the second one. Can you please tell me the difference between the two? Which one do you recommend? Thanks a lot

avatar image Bunny83 stevensu1838 · Jun 05, 2019 at 07:01 PM 0
Share

None of them ^^. Both Transform.eulerAngles and Transform.rotation.eulerAngles are calculated the same way from the quaternion rotation. Euler angles simply have too many issues for calculating delta information.


Ins$$anonymous$$d you may want to store the last rotation as Quaternion and calculate the difference between the old and the new one like this:

 Quaternion dif = lastRot * Quaternion.Inverse(transform.rotation);

To turn this into an actual rotation vector you want to use ToAngleAxis:

 float angle;
 Vector3 axis;
 dif.ToAngleAxis(out angle, out axis); 
 Vector3 angularVelocity = axis * angle / Time.deltaTime;

I haven't tested this but it should work. Note as i said if the actual angular velocity is too large (more than 180° per frame) it's impossible to get accurate information. There could be countless full turns between two measurements which you can not detect. Rotating at for example 270° pre frame would be equal to a rotation of -90° so the deter$$anonymous$$ed velocity would be the other way round (again wagon wheel effect as mentioned above).

Show more comments

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

168 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Rigid Body Wont transform 1 Answer

Calculate Local Velocity of a body at a specific point 0 Answers

different beetween transform.translat and rigidbody.addforce? 1 Answer

Velocity powered rigidbody on a moving platform without parenting. 3 Answers

Animation or smooth teleportation 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges