Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question How can I have a balloon rigidly attatched to a rigid body cause a critically damped rotation?

Discussion in 'Physics' started by Yellyad, Jul 28, 2023.

  1. Yellyad

    Yellyad

    Joined:
    Nov 5, 2022
    Posts:
    3
    Hey all,

    I'm working on a game right now that includes vehicles with balloons placed on a rigidbody which exert a restoring torque value according to how far they are from the COM, and the upwards force of the balloon. The problem with this is that balloon vehicles will oscillate back and forth across the y axis given that there is no damping applied.

    I have tried many different implementations to do this but I'm having difficulty understanding how exactly to accomplish this. Ideally I would want to get a torque value based on the restoring torque one that causes them to smoothly approach the center of the pendulum motion. Every time I have tried, the rigid body just spins erratically or the torque doesn't appear aligned right.

    Code (CSharp):
    1. private Vector3 CalcSmoothDampTorque(Vector3 force)
    2.     {
    3.         Vector3 dampTorque;
    4.         Vector3 rotVel = RB.angularVelocity;
    5.         Vector3 oldRotVel = RB.angularVelocity;
    6.         Vector3 aboveCOMeuler = new Vector3(0f, 0f, 180f);
    7.         Vector3 heliumEuler = Quaternion.FromToRotation(distanceToCOM.normalized, Vector3.up).eulerAngles;//RB.rotation.eulerAngles;
    8.         heliumEuler.y = 0f;
    9.         Vector3 moments = RB.inertiaTensor;
    10.  
    11.         float smoothTime = 2 * Mathf.PI * Mathf.Sqrt(distanceToCOM.magnitude) / (force.y / RB.mass); // period of pendulum = 2pi * qrt(length / acceleration)
    12.  
    13.         Vector3 newBotEuler = SmoothDampEuler(heliumEuler, aboveCOMeuler, ref rotVel, smoothTime);
    14.         Vector3 deltaV = rotVel - oldRotVel;
    15.         Vector3 angAccel = deltaV * Time.fixedDeltaTime; //deltaV / Time.fixedDeltaTime;
    16.         dampTorque = Vector3.Scale(moments, angAccel);
    17.         dampTorque.y = 0;
    18.  
    19.         Utility.Console.Log(heliumEuler + " -> " + newBotEuler);
    20.         Utility.Console.Log("euler between helium and COM: " + heliumEuler);
    21.         Utility.Console.Log("distance to COM: " + distanceToCOM);
    22.         Utility.Console.Log("torque applied: " + dampTorque);
    23.  
    24.         return dampTorque;
    25.     }
    26.     public static Vector3 SmoothDampEuler(Vector3 current, Vector3 target, ref Vector3 currentVelocity, float smoothTime)
    27.     {
    28.         return new Vector3(
    29.           Mathf.SmoothDampAngle(current.x, target.x, ref currentVelocity.x, smoothTime),
    30.           Mathf.SmoothDampAngle(current.y, target.y, ref currentVelocity.y, smoothTime),
    31.           Mathf.SmoothDampAngle(current.z, target.z, ref currentVelocity.z, smoothTime)
    32.         );
    33.     }
     
  2. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    577
    Can't you set angular drag?

    This will keep a rigidbody upright:
    Code (CSharp):
    1.             rb.angularDrag=10;
    2.             var rot = Quaternion.FromToRotation(transform.up, Vector3.up);
    3.             rb.AddTorque(new Vector3(rot.x, rot.y, rot.z)*10f,ForceMode.Impulse);
     
  3. zulo3d

    zulo3d

    Joined:
    Feb 18, 2023
    Posts:
    577
    If you don't want to set the angular drag for some reason then you can just apply an opposing force to dampen the angular velocity.

    Code (CSharp):
    1. rb.AddTorque(-rb.angularVelocity*0.9f,ForceMode.Impulse);
     
  4. Yellyad

    Yellyad

    Joined:
    Nov 5, 2022
    Posts:
    3
    I don't think I can just add angular drag to it since I need the rigidbody to not be dampened when doing other things, such as turning on the y-axis with thrusters. The second solution could work but for my implementation I'm looking for the rigid body to swing to the middle as fast as possible (based on the force the balloon exerts upwards) without oscillating over (which from what I can tell, is what critical damping is). I think just multiplying the velocity by an arbitrary number wouldn't quite accomplish that but I'm not super sure on the physics.