3
\$\begingroup\$

I have an object that is dragged by the mouse (X and Z positions) over a table, with the following simple code:

 Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
 if(Physics.Raycast(ray, out hit));
 pos = new Vector3(hit.point.x,myobject.transform.localScale.y/2,hit.point.z);
 myobject.GetComponent<Rigidbody>().MovePosition(pos);

The dragging works as expected. What I am struggling with is how can one retrieve the direction and velocity of such a movement, i.e. the direction and the velocity of that object when moved by being dragged by the mouse (I use Unity, C#). I have searched online, but only found the common ways to retrieve velocity and movement when using standard Rigidbody movement, not when dragged by the mouse.

\$\endgroup\$
  • \$\begingroup\$ Curious.. Is not the velocity of the object the same as the velocity of the mouse? Thus distance travelled by mouse <mx1-mx0, mz1-mz0) within a frame. Calculate the angle by atan2((mz1-mz0)/(mx1-mx0)). \$\endgroup\$ – Majte Oct 24 '15 at 2:04
2
\$\begingroup\$

The velocity is the difference between the new position and the last position.
velocity = newPos - oldPos

The vector direction is the normalized velocity.
direction = velocity.normalized

Rigidbody should update velocity each frame, even if you are using MovePosition(), however, if you need to know what the velocity will be before the object is actually moved, then you will have to calculate it.

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
if(Physics.Raycast(ray, out hit));
oldPos = myobject.transform.position;
newPos = new Vector3(hit.point.x,myobject.transform.localScale.y/2,hit.point.z);
myobject.GetComponent<Rigidbody>().MovePosition(pos);

Vector3 velocity = (newPos - oldPos);
Vector3 direction = velocity.normalized;

If you want the angle of the direction vector (or velocity, works the same) in 3D space, then you can use Vector3.Angle().

float worldDegrees = Vector3.Angle(Vector3.forward, direction); // angle relative to world space
float localDegrees = Vector3.Angle(myobject.transform.forward, direction); // angle relative to last heading of myobject
\$\endgroup\$
  • \$\begingroup\$ Thanks for your detailed reply! First thing is about what you've said on Rigidbodies updating velocity when moved with "MovePosition": "Debug.Log(myobject.GetComponent<Rigidbody>().velocity.ToString());" returns Vector3.zero, no matter what. Which means, Rigidbody isn't updating its velocity parameter when moving with "MovePosition". Second thing: on the other hand, your suggestion works perfectly! My mistake was: I was trying the same logic, but instead of "velocity = newPos - oldPos", I was doing "velocity = myobject.transform.position - oldPos", which gives me a Vector3.zero, don't know why \$\endgroup\$ – Louis15 Oct 24 '15 at 6:14
  • 1
    \$\begingroup\$ Note that MovePosition() does not update the position when the method is called but after FixedUpdate(). Eg. You can call it multiple times in a single frame but only the last call will have an affect. That might explain why your attempt with velocity = myobject.transform.position - oldPos returns Vector.zero. Unrelated but worth mentioning is that MovePosition() might not move your object to the target if the distance is too great. Moving with the mouse, it's probably not a concern but something to be aware of. The rigidbody physics limit how fast it can move per frame. \$\endgroup\$ – Fuzzy Logic Oct 24 '15 at 9:06
  • \$\begingroup\$ Great comment as well. You have make upvote for it also. In fact, I'm doing the MovePosition outside FixedUpdate() and your explanation makes total sense. I will give it a try. Also, thanks for the last remark. I didn't know that and it is certainly very useful for my project, although not regarding the dragged object. Thanks! \$\endgroup\$ – Louis15 Oct 24 '15 at 12:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.