How to Limit Rotation of Object Moved by Gravity?

I have a Child object, an Iron Bar (with Rigidbody and Gravity), connected to a Long Arm (w/ Rigidbody and isKinematic). I need to restrict the rotation of the Iron Bar from 1 to 40 degree angles only so it won’t go overboard and hit the Long Arm. Please refer to attached image for an illustration. I tried several approaches from using a Hinge Joint and its Limit options and also through code. But I cannot seem to solve this problem. Right now I have this script attached to the Iron Bar but it does not seem to have any effect.

public Transform targetTransform;
private Vector3 _currentAngle;
private Vector3 _targetAngle;
float rotationX;

void FixedUpdate () {

     transform.right = targetTransform.transform.right;
     
     rotationX = transform.eulerAngles.x;

     if (rotationX > 40) {
            _targetAngle = new Vector3 (40, transform.eulerAngles.y, transform.eulerAngles.z);
            _currentAngle = new Vector3 (
                Mathf.LerpAngle (transform.eulerAngles.x, _targetAngle.x, Time.deltaTime),
                Mathf.LerpAngle (transform.eulerAngles.y, _targetAngle.y, Time.deltaTime),
                Mathf.LerpAngle (transform.eulerAngles.z, _targetAngle.z, Time.deltaTime));
            transform.eulerAngles = _currentAngle;
        } else if (rotationX < 1) {
            _targetAngle = new Vector3 (1, transform.eulerAngles.y, transform.eulerAngles.z);
            _currentAngle = new Vector3 (
                Mathf.LerpAngle (transform.eulerAngles.x, _targetAngle.x, Time.deltaTime),
                Mathf.LerpAngle (transform.eulerAngles.y, _targetAngle.y, Time.deltaTime),
                Mathf.LerpAngle (transform.eulerAngles.z, _targetAngle.z, Time.deltaTime));
            transform.eulerAngles = _currentAngle;
        }

}

Would appreciate any help you can provide. Thanks for taking a look.

Good day.

You should take a look at Mathf.Clamp funtion! :smiley:

Bye!

By the way, please note the code I posted about Mathf.Clamp above still doesn’t work. I haven’t figured out the solution yet.

Just a long shot, but have you considered using a slightly larger box collider on the LongArm to arrest / repel the IronBar when it rotates wildly? Another solution could be that when you detect a large angle, you could apply a counter angular force (torque)?

Apply torque

Hi Rendcyle,

Your problem really interested me and sent me into a nice learning journey into physics and vehicles :slight_smile:

I have taken the liberty of making a small package with some code and physics vehicle setup (download package from here) that demonstrates a moving physics driven crane, that can articulate its long arm to lift and lower a swinging payload. Drive the crane with arrow keys, and brake/lower/lift arm with space key.

I have purposely added some debris, allowed it to ram into the edges, and also did hard-braking to test the behavior of the swinging payload. I think the chain setup can still be improved, but I am mighty happy with this short project! Please do share your comments.

PS. I have made some compromises to turn off active rigid body collision in some parts of the crane, so that internal collisions don’t make the crane go crazy, as you had suggested. Also, I left the short arm out of the crane setup, for more dynamic response to crane motion. You can include it within the crane if you want more controlled behavior.

Hi RendCycle,

I am glad you found my sandbox useful. Your new ramp challenge kept me busy for 6 hours before I could come to a stable solution. Please find the updates in the unity package here.

  1. Removed active physics from TopEnd and reabsorbed it under LongArm passive bodies. I spent almost 70% time trying to stabilize this piece. I managed to calm it down for normal lift/load using hinge rotation limits, but it got too much once the heavy crane started moving around. Since there are 4 chains depending on this one piece, I would advise keeping it passive. I know that the aesthetics of a gravity-influenced chain-root looks nice, but it creates too much instability. I also tried correcting the passive version with Rigidbody.MoveRotation to simulate gravity, but the moment I do this correction to TopEnd, the Hinge constraint stops working (note, this works perfectly for a normal passive rigidbody which has no active elements attached to it; i.e. a copy of the long arm without any chain links worked fine)
  2. Removed colliders from chain links to reduce unnecessary infighting, especially once the base plate goes flying around wildly, and during a collapsed chain state after lowering the arm.
  3. Increased each chain link mass to 300 to prevent tearing, especially during sudden jerks and ramp movement. Keeping the base plate and chains heavy, will help them from flying about lesser when large forces from the 1.5ton body are raging through the system (during swerves, sudden change in slope, sudden braking and external collisions)
  4. Introduced limits of +/-15 degree rotation on chain links to reduce wild swings
  5. Made the crane 4-wheel driven to spread the forces more evenly through the body
  6. Removed reference to the rotation axis correction script as TopEnd is now a passive child

I hope you find this update useful to your project. Do share your final work once ready. I wish you good luck!