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;
}
Answer by streeetwalker · Oct 01, 2020 at 09:40 AM
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.
Answer by philekiert · Oct 01, 2020 at 05:30 PM
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.
well, perhaps I misunderstood what you meant by inertia, which I take to mean want something to keep rotating once it starts rotating.
But I think that is a separate problem. No matter if it rotates in sudden jumps and then stops, or it keeps rotating, I think the rotation problem you have is that you keep applying the rotation aligned to the new orientation of the object.
It seems to me that what you want is to make the object rotate, no matter when the force is applied to the respective axes, as though the axes did not alter the orientation of the object - as though the thrusters were not attached to the object but apply thrust apart from its changing orientation.
The result to you should be - what you want is, for example: if you apply thrust on the nose of the ship, you want it to pitch over end-over-end. And if you then apply thrust on the sides at anytime, you want object to then roll about the z axis without altering the end-over-end pitching attitude. (And visa-versa...) Is that right?
Of course, that is not how a real spaceship would behave if thrusters were actually attached to the space ship.... but if that is what you want, it is doable, but I need to know
I hope that clarifies what i wrote.
Thanks for sticking with me. I think I'm just having trouble explaining myself, so I recorded a quick example of what's going on.
In the video, I'm tapping the pitch-up button to add some rotational inertia around X, and then after one full rotation, I'm tapping the roll left button to add some rotational inertia around the ship's Z axis. What I want to happen is what would happen in space. What is happening is that my rotational inertia quaternions are causing rotation each frame relative to the ship's current local X/Y/Z axes. Given the two brief inputs in the video (a single push to pitch, then a push to roll), the rotation around X shouldn't deviate from global X unless you initiate a pitch somewhere during a roll. For this reason, I can't just tie the pitch to global X, because X will shift once someone tries to steer the ship left or right, it's just that in my example above, it should remain aligned with global X.
I hope that makes my issue a bit clearer?
There is no true inertia being simulated in your system - the math required in the statements is not there. You are simulating inertia by applying a rotational change each frame.
What you are showing in the video is exactly what I understood, and exactly what would happen in a real ship if you do not hit the roll thruster at exactly the right moment, which I suspect you are not.
I mean, do you have some way to verify that pitch is at zero the moment you apply a roll? If you are even 1 frame off your code is going to produce the tumbling you are getting.
You've got me going now because this is an interesting problem - so give me a little while to code up an example.
Your answer
![](https://koobas.hobune.stream/wayback/20220613012850im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
How to detect if a GameObject is currently rotating? 1 Answer
Make GameObject rotate around another around random axis but with fixed distance 0 Answers
ROTATION STOPS when i move the char on the air! 0 Answers
Turret rotation based on its own local rotation. 3 Answers
Assign an object rotation along a single axis from other object's rotation. 0 Answers