- Home /
How to rotate an object around its 3 axis and translate it on 2 world axis so it looks like its a dice rolling?
Hi everyone, I am new to unity and I am trying to rotate a dice around its 3 axis and translate it at the same time on 2 axis. The problem I am facing is if I rotate it without translating it works fine and same for translating without rotating, but once I do both together it starts rotating in a weird way and not around itself and it also doesn't translate the way it is supposed to. Can someone help me figure out what I am missing here ? Thanks!
This what I am doing:
Vector3 center = gameObject.collider.bounds.center; gameObject.transform.Translate(velocity); gameObject.transform.RotateAround(center,Vector3.right,angularVelocity.x); gameObject.transform.RotateAround(center,Vector3.up,angularVelocity.y); gameObject.transform.RotateAround(center,Vector3.forward,angularVelocity.z);
Answer by whydoidoit · May 17, 2013 at 07:00 PM
Well you are moving it in local space so that sorts your weird movement out. If the dice is modelled centrally then all of those rotate arounds are probably a bit much too, and you aren't using Time.deltaTime so the rotation and movement isn't frame rate independent.
Vector3 center = gameObject.collider.bounds.center;
gameObject.transform.Translate(velocity * Time.deltaTime, Space.World);
gameObject.transform.RotateAround(center,Vector3.right,angularVelocity.x * Time.deltaTime);
gameObject.transform.RotateAround(center,Vector3.up,angularVelocity.y * Time.deltaTime);
gameObject.transform.RotateAround(center,Vector3.forward,angularVelocity.z * Time.deltaTime);
I would probably have done this, which might work for you:
var t = gameObject.transform;
t.position += velocity * Time.deltaTime;
var angle = t.eulerAngles;
angle += angularVelocity * Time.deltaTime;
t.eulerAngles = angle;
Thanks for the answers, but yeah I am using the collider bounds to calculate the center of rotation because the pivot point is not at the center of my dice, I will be fixing that soon.
But Whydoidoit is right, the problem I am seeing is mostly with the translation, if I translate without rotating the dice goes in an upward/right direction, but once I try to rotate the dice while translating it will change direction according to the dice's local axis, it will start by going upward and as the dice rotate it will start translating in a circular position almost. Is there a way to translate the dice in a certain direction regardless of its rotation ?
Thanks!
So firstly - don't post comments as answers, on UA Answer means Solution and not Reply. There's an add new comment button hidden on the right. - I converted it for you, your Answers currently require moderation while your comments do not.
The first part of my answer does that translation for you while maintaining your RotateAround logic.
Basically use Space.World and then also multiply by Time.deltaTime (increasing your velocity if it gets too slow after doing that).
I couldn't find the Add new comment button, had to google it and someone suggested clearing my browser's cache...it seems that it fixed it..and yes the first part of your answer solved it for me..Thanks!
Answer by robertbu · May 17, 2013 at 07:05 PM
My guess is the issue is your use of the collider bounds to calculate the center of rotation. Is there a particular reason why you are using the center of the collider? Is it because the pivot point is not at the center of your dice? If so you can either 1) re-author in your 3D editor program, 2) Use the SetPivot editor script, or 3) make the visible object a child of an empty game object positioned at the correct pivot point. Once you do that, you can do something this to make them roll:
Transform.Rotate(angularVelocity * Time.deltaTime, Space.Self);
The movement's wrong because the translation is in local space though don't you think? (tumbling velocity is not related to the rotation of the body).
@whydoidoit - you are right, and I missed it. I was trying to figure out how the RotateAround() center was moving:
transform.Rotate(angularVelocity*Time.deltaTime, Space.Self);
transform.Translate(velocity*Time.deltaTime, Space.World);
Thanx so much... i got my solution of translating and rotating by these two line...
transform.Rotate(angularVelocity*Time.deltaTime, Space.Self);
transform.Translate(velocity*Time.deltaTime, Space.World);
Answer by bigbat · May 17, 2013 at 07:27 PM
I think changing your movement code to something like this solve the problem : transform.translate( velocity*Time. deltatime,space.world );