How set rotation of a single axis
I am making a spaceship game, and in the game the ship can move forward, backwards, right, and left, and it can turn up, down, right and left. The problem is with the two-axis turning: when you turn one way and then the other, you end up in a roll position. Is there a way to set the rotation so as to prevent a roll without resetting all the rotation axis's value? In other words, is there a way to set the x-rotation to, say, 0 from whatever it is without changing y and z?
@useralpha - Hi, I'm not sure but are you describing a gimbal lock situation? I'm not quite sure based on the description. You can set rotations by Euler angles but internally they are Quaternions...
Answer by Sgt_Spike · Aug 25, 2018 at 07:20 PM
Hey there. Not 100% sure it will work but maybe you could try using this:
yourObjectName.transform.Rotate(yourXVariable, yourObjectName.y, yourObjectName.z)
Make a float for the x variable and change 'yourXVariable' with that float. Or you could just set that x value to any number.
Hopefully it works! :D
Well, that wasn't quite it, but I played around a bit and now it works rather well. In the end, I put:
in Start():
float levelRotationX = transform.rotation.x;
in FixedUpdate():
transform.Rotate(levelRotationX - transform.rotation.x, 0, 0);
this allows the player to stay point upwards if they want, but the anti-rolling sometimes rotates to the wrong point. The other option was doing:
in Start():
float levelRotationX = transform.rotation.x;
float levelRotationZ = transform.rotation.z;
in FixedUpdate():
transform.Rotate(levelRotationX - transform.rotation.x, 0, levelRotationZ - transform.rotation.z);
but that means that it will also reset the up/down tilt of the ship. not sure what is better :)
Eh, well perhaps you could use a boolean or something to stop the other axis moving. Again, not sure if this will make the problem better or worse. Looking at the code you provided it looks like you need to only rotate on the x and z axis' and the y axis is not used at all. If that's correct make a boolean called 'rotateX' or something. Then when your player needs to rotate on the x axis, set it to true, whilst if it's the z axis set it to false. You can make the code sort of like this.
public static bool rotateX
Start()
{
float levelRotationX = transform.rotation.x;
float levelRotationZ = transform.rotation.z;
}
FixedUpdate()
{
if(rotateX == true)
{
transform.Rotate(levelRotationX - transform.rotation.x, 0, transform.rotation.z);
} else
{
transform.Rotate(transform.rotation.x, 0, levelRotationZ - transform.rotation.z);
}
}
Then just change that boolean from the script that makes your player move. Again, not too sure if this will make it any better or not. Have a look into that and see if you can get it to work! Good luck!
Yeah, I think that that is what I will do, and I'll make it so the player can change the bool in-game, since alone, neither option covers everything. Either that or the player will manually control rolling, but that would mean 10 buttons to control basic movement alone. :/