- Home /
Constant 3D rotation (torque, angular acceleration, etc) GLOBAL to object in space?
Hey all,
Imagine a ship in space - it rolls to the right, then yaws left. It SHOULD roll in the direction it originally rolled ('right'), forever, regardless of how it yaws. At the moment, the constant roll value is being applied to it in a local sense, i.e. it will roll to the 'right' of the ship's nose (clock-wise), no matter which way you point the ship after the fact. When rolling, for example, this is the simple code, where m_rollPercentage is used to make the angular acceleration increase gradually, and 10000 is an arbitrary place-holder for the power of the ship's thrusters;
void RollRight()
{
m_rollPercentage += 0.10f;
m_torque.z += m_rollPercentage * 10000;
}
And this is the code to update the rotation for the object:
void UpdateRotation()
{
Quaternion convertedRotation = Quaternion.AngleAxis(m_angularVelocity.x * Time.deltaTime, transform.right);
m_additionalRotation = convertedRotation * m_additionalRotation;
convertedRotation = Quaternion.AngleAxis(m_angularVelocity.y * Time.deltaTime, transform.forward);
m_additionalRotation = convertedRotation * m_additionalRotation;
convertedRotation = Quaternion.AngleAxis(m_angularVelocity.z * Time.deltaTime, transform.up);
m_additionalRotation = convertedRotation * m_additionalRotation;
m_additionalRotation = convertedRotation * m_additionalRotation;
m_rotationAngle += m_angularVelocity * Time.deltaTime;
m_angularAcceleration = m_torque / m_momentOfIntertia;
m_angularVelocity += m_angularAcceleration * Time.deltaTime;
m_additionalRotation = NormalizeQuaternion(m_additionalRotation);
gameObject.transform.rotation = m_additionalRotation;
m_torque = Vector3.zero;
}
I've been trying to solve this issue for a while, so any advice would be great!
- HateDread
Answer by raimon.massanet · Jan 07, 2014 at 12:50 PM
Instead of using the local axes (`transform.right`), use world axes (`Vector3.right`), for the rotations that should be global.
The issue is that the torque must be added local to the craft, but the craft must rotate globally. If I simply change Transform to Vector3 in the axis rotation section, the craft will only rotate correctly from its initial 0-rotation position. As soon as it rotates in any direction, all over rotations are skewed.
If it rolls 90 degrees, the controls for yaw are suddenly for pitch, and so-on. It is adding the torque presu$$anonymous$$g the craft is always at a 0 rotation on all axes.
Then I don't understand what your are trying to do. Adding a torque locally but rotating globally does not make any sense to me.
I would say both torque and rotation should be applied locally. If the ship rolls 90 degrees, then yes, yaw becomes pitch, and if it rolls 180 degrees, then pitch is inverted (from the user's static point of view), nobody said flying inverted was easy ;-)
What is the intended behavior? $$anonymous$$aybe what you are trying to do is to show a rotated ship, but make its controlls unaffected by the rotation?
Hey Raimon,
That last part is more on the right track... you'll be piloting it in first/third person, so the camera rotates with it. Thus, the roll key should always roll the ship, even if you're yawed, pitched, etc, globally.
There are two issues.
Firstly, adding the torque in a way that takes the craft's rotation into account (and so a roll rotation is applied relative to the ship's rotation, making it roll regardless of its orientation in the world).
And secondly, allowing the angular velocity to remain constant (as there is no damping force used). If I add the torque locally, but use the angular velocity vector without taking rotation into account, I am simply rotating the craft as if it were at (0, 0, 0) rotation, and thus if it is pointed in ANY other direction, the rotation is totally wrong, and the ship is very unintuitive to control.
Does this make a little more sense? I'm having trouble vocalising my thoughts, and am still trying to remember the difference between local and global in terms of rotations.
Thanks.
Why are you not using Rigidbody.AddTorque
ins$$anonymous$$d of managing the object's rotation by yourself?
I am leaving you a code I wrote for controlling a ship using AddTorque
. The code assumes the game object has a rigidbody
attached to it. If you play around with the body's mass and angular drag you will be able to fine tune the ship's maneuverability.
using UnityEngine;
using System.Collections;
public class SpaceShipControl : $$anonymous$$onoBehaviour
{
// Update is called once per frame
void FixedUpdate ()
{
// Yaw left
if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.Q))
{
rigidbody.AddTorque(transform.up * -1, Force$$anonymous$$ode.Force);
}
// Yaw right
else if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.E))
{
rigidbody.AddTorque(transform.up, Force$$anonymous$$ode.Force);
}
// Roll left
if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.A))
{
rigidbody.AddTorque(transform.forward, Force$$anonymous$$ode.Force);
}
// Roll right
else if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.D))
{
rigidbody.AddTorque(transform.forward * -1, Force$$anonymous$$ode.Force);
}
// $$anonymous$$ch down
if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.W))
{
rigidbody.AddTorque(transform.right, Force$$anonymous$$ode.Force);
}
// $$anonymous$$ch up
else if(Input.Get$$anonymous$$ey($$anonymous$$eyCode.S))
{
rigidbody.AddTorque(transform.right * -1, Force$$anonymous$$ode.Force);
}
}
}