First Encounter with Gimbal Lock – Need Help

Hi everyone,

This is my first encounter with gimbal lock, and I can’t quite wrap my head around it.

I’m working on simulating a soft robot arm that is controlled by 4 ropes. The black dots represent the pull points, which turn red when pulling backward and green when pulling forward. (Just to clarify, this isn’t for a game; I simply didn’t know how else to approach it.)

To make this work, I slightly move the black dots and then align the blue disc to the plane they form. However, when trying to align it, I encounter gimbal lock.

Additionally, to ensure that movement translates smoothly from one part to another, all objects are children of the preceding object.

I can’t attach a video of the robot right now since I’m a new user, but I can share my code for the alignment or try to describe the issue further if needed.

Any help or insight would be greatly appreciated!

using UnityEngine;
using System.Collections.Generic;

public class AlignToPlane : MonoBehaviour
{
    public List<Transform> points; // List of points
    public Transform disk; // Disk object

    void Update()
    {
        if (points.Count < 4) return; // Ensure there are at least 4 points

        // Step 1: Calculate the center position
        Vector3 center = Vector3.zero;
        foreach (Transform point in points)
        {
            center += point.position;
        }
        center /= points.Count;

        // Step 2: Compute the normal vector of the plane
        Vector3 v1 = points[1].position - points[0].position;
        Vector3 v2 = points[2].position - points[0].position;
        Vector3 normal = Vector3.Cross(v1, v2).normalized;

        // Step 3: Calculate the rotation based on the normal
        Quaternion rotation = Quaternion.LookRotation(normal, Vector3.up);


        // Step 4: Apply the position and rotation to the GameObject
        transform.position = center;
        transform.rotation = rotation * Quaternion.Euler(0, -180, 0);

        disk.position = center;
        disk.rotation = rotation * Quaternion.Euler(90, 0, 0);

    }
}

I’ve attached an image showing the problem I’m facing since, as a new user, I can only upload one image.

To explain the setup: I have a soft robot arm with 3 sections that can be pulled independently. In this image, I’ve pulled on both the 3rd and 2nd sections. However, the 3rd section is stuck pointing upwards.

I believe this issue is caused by gimbal lock, but I’m not entirely sure. Any guidance or suggestions on how to fix this would be greatly appreciated!

Instead of

Quaternion rotation = Quaternion.LookRotation(normal, Vector3.up);

use

disc.forward = normal
or
disc.up = normal

PS: this isn’t a gimbal lock. People need to stop calling every rotation issue a gimbal lock problem. xD This is just the way Quaternion.LookRotation operates. You could also solve it by using something else than “Vector3.up” for the up vector. Actually you probably should use the normal for the up vector and any calculated perpendicular vector for the forward one. But my suggestion should be much simpler and less of a headache.

Edit: why are you even setting transform.rotation? I don’t quire understand why you rotate the object with the controller script at all. Where is this script attacked? What does the hierarchy look like?

Thanks for the clarification! I appreciate the suggestion and the explanation about Quaternion.LookRotation—I’ll give your method a try.

To answer your question about the hierarchy: the cylinder you see is purely for aesthetics. Its rotation and scale are only for visual purposes and don’t affect the functionality. The GameObject with the script is what actually handles the logic, and it’s the one that has children.

Also, my bad for calling it gimbal lock! I thought that’s what was happening, but I see now that it’s not the case. Thanks for pointing that out.


Let me know if you have any further thoughts or suggestions!
(the circle points in the hierarchy are the balls that are pulled an pushed)