Incrementing Rotation Produces Strange Transform Values

At this stage in my project I have a bridge the player is standing on. When he walks over a button, the bridge needs to rotate by 72 degrees (1/5 of a full rotation) around its local X axis, which coincides with the pillar supporting it. This interpolation needs to ease out and in.

The script I’m currently using works by rotating the bridge by a certain increment around its X axis every update until the desired rotation is reached or exceeded, at which point it stops rotating and snaps to the proper value.

The bridge starts with an x rotation value of 288, or 360 - 72 degrees. Its y rotation is 328.3 degrees, which is the value needed for the x axis to be pointing the right direction. It’s z rotation is 0.

But there’s an issue. The script works perfectly the first three times, and then goes haywire. It rotates smoothly to 360 or 0 degrees, and then to 72 degrees. THEN, when I rotate it the third time, as the x rotation reaches 90 degrees, the y and z rotations suddenly change even though I didn’t tell them to, and the x rotation begins incrementing downwards instead of upwards. In the game view, the rotation continues uninterrupted and it snaps properly. But now its x rotation is no longer the expected 144 degrees. Instead, it ends up around 36 degrees. This causes problems in the following rotation.

When the rotating process is finished, my code tells the bridge to snap its x rotation to a value equal to its initial x rotation (set before each rotation begins) plus a specific value (in this case, 72). So when I rotate the bridge a fourth time, it rotates smoothly to the new position, but then snaps to 108 (36 + 72), which is completely wrong.

Here is the code. It’s attached to the trigger that the player walks through.

        private var triggerTag : String = "Player";
        public var bridge : GameObject;
        public var character : GameObject;
        public var rotationSpeed : float = 5f;
        public var rotating : boolean = false;
        public var ROT : float = 72f;
        public var min : float = 0f;
        public var max : float = 10.0f;
        private var rotIncrement : float = 0f;
        private var currentRot : float = 0f;
        private var initialRot : float = 0f;
        private var rotAmount : float = 0f;
        function OnTriggerEnter (other : Collider) {
        if (other.CompareTag(triggerTag) && !rotating) {
        	rotAmount = ROT;
        	character.transform.parent = bridge.transform;
        	initialRot = bridge.transform.localEulerAngles.x;
        function Update () {
        print (bridge.transform.localEulerAngles);
        	if (currentRot < rotAmount) {
        	rotating = true;
        	} else {
        	if (currentRot > rotAmount) {
        	bridge.transform.localEulerAngles = Vector3(initialRot + rotAmount, 328.3, 0.0);
        	character.transform.parent = null;
        	Reset ();
        	} else {
        	rotating = false;
        	if (rotating && (currentRot < (rotAmount)/2)){
        		rotIncrement += 0.01 * rotationSpeed * Time.deltaTime;
        		rotIncrement = Mathf.Clamp (rotIncrement, min, max);
        		bridge.transform.Rotate(rotIncrement, 0, 0, Space.Self);
        	} else {
        	if (rotating) {
        		rotIncrement -= 0.009 * rotationSpeed * Time.deltaTime;
        		rotIncrement = Mathf.Clamp (rotIncrement, min, max);
        		bridge.transform.Rotate(rotIncrement, 0, 0, Space.Self);
    	currentRot += rotIncrement;
    	function Reset () {
    		rotating = false;
    		rotAmount = 0f;
    		currentRot = 0f;
    		rotIncrement = 0f;
    		initialRot = 0f;

While looking around online, someone mentioned Gimbal Locking, which I am only semi-familiar with. Could this be causing the issue? I know that Quaternion functions avoid Gimbal locking, but I’ve been avoiding them because I want the rotation of my bridge to ease in and out smoothly, and I don’t know of a Quaternion function that achieves this result.

Can anyone come up with a solution?

Here are some images in case the description wasn’t clear enough:

After Second Rotation:

After Third Rotation, when things get weird:

You can use a Quaternion Lerp ( Unity - Scripting API: Quaternion.Lerp ) to smoothly interpolate between two orientations. Create a ‘start’ orientation for the object and a ‘end’ orientation. Then calculate the intermediate rotation using Lerp for increasing t values between 0.0 and 1.0