I’ve done as much searching as possible (and a whole lot of experimenting), but I can’t quite seem to solve this problem I’m having. Essentially I want to rotate an object on two axes simultaneously, but independently. I’ve drawn a quick sketch to show what I mean:
Ideally I’d like both rotations to be physics (rigidbody) based, but I’m happy to settle for an approximation using slerps. The closest I’ve come so far is by using a rotation for the Y rotation:
transform.RotateAround(transform.position, transform.up, rotateForce);
Whilst using torque for the Z rotation:
rigidbody.AddRelativeTorque(Vector3.forward * tiltForce);
This works, but is nowhere near robust and the object quickly ends up in strange positions, for example rotated around its X axis (I’d like to avoid any rotation in the X axis if at all possible?).
I’m pretty stumped, so some tips to get me looking in the right direction would be very helpful. I’ve got this nagging feeling I should be doing something with Quaternions, but I’m not quite sure what! Thanks very much.
Th usual approach is to separate the rotation. Parent the object to an Empty, rotate that around the global Z-axis and rotate the child around it’s local Y-axis.
OK, as always (in my case at least), resorting to posting on a forum always guarantees I’ll figure it out. For those who come here looking for the answer, here’s my solution:
// Rotate around Y axis
transform.RotateAround(transform.up,Time.deltaTime * YForce);
// Rotate around Z axis
transform.RotateAround(Vector3.forward, Time.deltaTime * ZForce);
Place these in update() or fixedupdate() and create the YForce/ZForce variables to be whatever you want (I’m getting input from an Xbox controller).
Why can’t you just use
transform.Rotate(new Vector3(0, yRotation, zRotation), Space.Self);? That should rotate the transform by ‘yRotation’ units around the local y-axis and ‘zRotation’ units around the local z-axis
After 16 hours, I got my two axes rotating cleanly. And I did indeed have to use parenting — but even that didn’t work for a long time
I just wanted to have code that causes an object to turn in circles and also front flip as it turns. OR IN OTHER WORDS: rotate yaw and pitch without any effect on roll.
Here’s what finally worked.
- Create an empty. Call it ForYaw.
- Give that a child empty, called ForPitch.
- Finally, make a cube and move it to z= 5 (forward). Now we can see what we are trying to avoid, which will be twisting the cube (accidental “roll” while we yaw and pitch).
So you have YawObject/PitchObject/Mesh to see. However, the details of the above don’t matter much. As long as PitchObject is child, what happens next should work.
Now, using C# in Visual Studio or whatever, do your setup. This goes in Update:
objectForYaw.Rotate(objectForYaw.up, 1f, Space.World);
objectForPitch.Rotate(objectForPitch.right, 3f, Space.World);
//this will work on the pitch object as well
// (objectForPitch.position, objectForPitch.right, 3f);
That’s what worked for me! Good luck!
Note that it all broke for me when I tried to vary the order of parenting. It also breaks if I change Space.World for the child pitch object.
Yes, I could use Quaternion functions… on the parent. The parent-Yaw object is pretty tough. But Quaternion approaches failed me for the pitch. I really needed Rotate, or RotateAround (applied carefully) .
I’m confused for sure. I could definitely use some clarification on why I had to take a local axis but apply it through world space. Even in my solution, why does Space.Self ruin everything?
Using the parent and the child works with Rotate method but not with AddTorque, any ideas?