Having trouble with realistic rotational inertia in a space sim.

I’m having trouble with rotational inertia around more than one axis on my ship. The code below isn’t the actual code in my game, but it’s the basic gist of it and I’ve tried to make it as straight to the point as possible.

The ship rolls and pitches in the most basic way, I’m not taking mass distribution or position of the thrusters or anything like that into account, so it always rotates exactly around its own centre. You should be able to initiate a roll or pitch, and the ship should then continue to rotate on its own rotational inertia until you counter it.

The reason my approach is wrong is that if you initiate a pitch around X and a roll around Z with the same force, it should do a complete 360° flip around X while rotating around its own Z-axis.

With mine, each frame it rotates by 1 around its own Z, then by 1 around its own X, which shifts the Z-axis slightly so the next frame its pitch rotation is now tilted slightly to one side, leading to it facing 90° to one side halfway through its rotation and upside down, then back to its starting position. From what I understand, I need to separate the rotational inertia and from the added torque from the player, but I just can’t seem to get my head around it.

What’s the correct way to do this?

float pitch;
Quaternion pitchInertia = Quaternion.identity;
float roll;
Quaternion rollInertia = Quaternion.identity;

void Update()
{
    if (rollRight) roll = 1;
    else if (rollLeft) roll = -1;
    else roll = 0;
    if (pitchUp) pitch = 1;
    else if (pitchDown) pitch = -1;
    else pitch = 0;

    pitchInertia *= Quaternion.AngleAxis(pitch, Vector3.right);
    rollInertia *= Quaternion.AngleAxis(roll, Vector3.forward);

    transform.rotation *= rollInertia * pitchInertia;
}

You are getting realistic rotation, if you think about it. The problem is your frame of reference.

Imagine you have thrusters fixed to the sides of your spaceship to control the roll, and also on the nose to control the pitch:

If you apply side thrust to initiate a roll, and then apply thrust to the nose, of course the object will start to tumble, because the nose thrusters will now be pointing in a new direction that is no longer oriented with world Up and Down.

It appears your conception is that the thrusters should be fixed to world coordinates and not rotate with the ship.

The easy way to get the kind of rotation I think you are aiming for you’ll need to separate the x axis rotation from z hierarchically. That is parent your object. Apply pitch rotation to the parent, and roll to the child, and you will get the type of overall rotation it seems you want.

Otherwise you’re going to have to go through some complex Quaternion arithmetic - I have a decent math and physics background, but this would take me quite a while to work out. Perhaps someone else is better than I am at this. You might post a query math stackoverflow.

All that said, if you instead use the rigidbody physics engine and apply torque forces, I believe that might take care of the issue for you.

[edit] After some thought, maybe there is an easier way - I think the problem described above is a result of your last line of code: if you calculate the entire rotation and do not add it to the existing rotation in your last line of code, that I think solves the problem for you. So keep a running variable for the x and z degrees, calculate the overall current rotation from those, and set your object rotation to the result.

I’m not sure it is realistic. I may be having some trouble explaining myself properly.

Say we have a pen in space. We tap on the end to start it pitching around X. After one full rotation, we lightly brush one side at the middle to initiate a roll along with its current pitch (let’s ignore any unintentional push from your finger for this example). In my head, it should keep spinning around global X, and start rolling around its long axis/local Z axis. The only reason its rotation around X should shift from the global X axis since its initial thrust is if we then apply pitch at some point during the roll.

What’s happening in my code, frame by frame, is that it pitches up by 1, then rolls by 1, then pitches up 1 along its new local X axis, then rolls by 1 along its new local Z axis, etc. So I end up with the nib of the pen, so to speak, drawing a circle in one of its forward quadrants (really sorry about my terminology, trying to explain without any background in this stuff!). It’s as if there is no rotational inertia whatsoever, and instead it’s just permanent thrust from the nose and side.

Thanks for responding by the way, sorry to babble on a bit. But in response to what you said, I definitely want the thrusters to rotate with the ship. It’s just they should be inactive except for to initiate or shift a rotation.