Hinge Joint won't stay in place when moving GameObject

I’m trying to simulate a classic pendulum science experiment on unity.
So just for a prototype, I attach a hinge joint on my weight(pendulum) with a connected body of a gameObject(anchor).
Everything works fine until I try to move the weight programmatically.
It seems like whenever I tried to move the mass, the hinge joint anchor won’t stay in place. I’m not sure if this is a physics problem or scripting problem.
I checked the inspector and the anchor axis doesn’t seemed to change.
Below is the GIF of my problem, and a script of how I move my weight programmatically.
The red circle shows the anchor not staying in place when i click or move the weight, and the grey circle is just a guide of where the anchor should be.

7414010--906794--Sequence 02_1.gif

    void OnMouseDown() {
        gameObject.GetComponent<Rigidbody>().isKinematic = true;
        //destroyJoint();
        UpdateAnchorControlPlane();
        UpdatePendulumPosition();
    }

    void OnMouseDrag() {
        UpdatePendulumPosition();
    }

    private void OnMouseUp()
    {
        //recreateJoint();
        gameObject.GetComponent<Rigidbody>().isKinematic = false;
    }

    void UpdateAnchorControlPlane() {
        Vector3 anchorPos = anchorTransf.position;
        anchorControlPlane.Set3Points(anchorPos + Vector3.forward, anchorPos + Vector3.up, anchorPos + Vector3.back);
    }

    void UpdatePendulumPosition() {
        Vector3 anchorPosition = anchorTransf.position;
        Vector3 posDifference = GetPlanePoint(Input.mousePosition) - anchorPosition;
        posDifference = ClampToMagnitude(posDifference, minPower, maxPower);

        pendulumTransf.transform.position = anchorPosition + posDifference;
        pendulumTransf.transform.LookAt(anchorPosition, Vector3.left);
    }

    Vector3 GetPlanePoint(Vector3 pos) {
        float distance;

        Ray ray = cam.ScreenPointToRay(pos);
        if(anchorControlPlane.Raycast(ray, out distance)) {
            return ray.GetPoint(distance);
        }

        return pos;
    }

Can anyone please tell me how can I fix this? Thanks

Manipulating the transform directly bypasses the physics engine (lines 28 and 29 above).

When you have a Rigidbody, only use the .MovePosition() and .MoveRotation() methods on the RB instance.

1 Like

First of, thanks. I tried changing it to move the RB and it works. The anchor now stays in place.

But, I have another problem that came up. The pendulum works fine, but when it’s rotation or the swinging angle reach somewhere about 1 to 2 degree, it began to swing all over the place like below.
I not sure how to fix this as there is no script that changes or update the weight’s position and rotation. I just use unity’s hinge joint and gravity to do its work.
This problem is consistent to happen when the swinging angle is less than 2 degree and when it is about to stop.
7416857--907301--Sequence 02.gif

Possibly related to gimbal lock, but I don’t see rotation code above.

Generally, some notes on clamping rotation and NOT using .eulerAngles because of gimbal lock:

1 Like

Thanks a lot kurt. I found out the problem, it seemed like I put the wrong axis on the Quaternion.Euler as (x, y ,x) instead of x,y,z.

Really appreciate the help though. And Thank you.!

For those that wonder how I change from manipulating the transform.position to manipulating the rigidbody, here’s the modification

  1. Change line 28 for position (code above) to:
    pendulumTransf.GetComponent<Rigidbody>().MovePosition(anchorPosition + posDifference);

  2. Change line 29 for rotation to a function:

    void lookAt()
    {
        var localTarget = transform.InverseTransformPoint(anchor.transform.position);
        float angle = traceAngle.transform.eulerAngles.x - 90f;
        if (transform.position.z > 0) angle *= -1;
        Vector3 eulerAngleVelocity = new Vector3(angle, 0, 0);
        Quaternion deltaRotation = Quaternion.Euler(eulerAngleVelocity);
        pendulumTransf.GetComponent<Rigidbody>().MoveRotation(Quaternion.AngleAxis(angle, Vector3.left));
    }

Really big thanks to Kurt-Dekker with the swift response and help!

1 Like