Search Unity

Question Different maxAngularVelocity for different axis?

Discussion in 'Physics' started by fhedl, Jun 10, 2023.

  1. fhedl

    fhedl

    Joined:
    Apr 12, 2023
    Posts:
    1
    Hello, Unity noob here trying to code buoyancy physics for a floating vessel. I'm basically trying to achieve a lightweight buoyancy simulation for a ship. Currently I'm having trouble creating realistic pitch and roll for the vessel. Since the ship is much longer than it is wide, it should experience significantly more resistance when pitching, as compared to rolling. When I limit rotation of the rigidbody to isolate either pitching or rolling for testing purposes, I experimentally find that the maxAngularVelocity should be roughly 1.0 for rolling, and 0.015 for pitching. Any in-between value will result in unrealistic motion in both axis. I have tried a few different custom methods of lowering the max angular velocity in only the z-axis (pitch), but none have successfully overridden the maxAngularVelocity of the rigidbody, hence the problem persists. Any tips would be greatly appreciated.

    The code below is my latest attempt of clamping the z-axis velocity, but printing the velocity in Update() clearly shows the velocity's z-value reaches the max value of 1, rather than 0.015, as hoped.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class BuoyantForceUpdate : MonoBehaviour
    6. {
    7.     public Rigidbody ShipRB;
    8.     public UpdateCentreOfBuoyancy COBUpdate;
    9.     public ChildVisibilityController CVC;
    10.     public GameObject CGSphere;
    11.     public GameObject CBSphere;
    12.  
    13.     //public float ForceMultiplier = 100f;
    14.  
    15.     private float[] forceBuffer;
    16.     private Vector3[] CBBuffer;
    17.     private int bufferIndex;
    18.     private int bufferSize;
    19.  
    20.     // Start is called before the first frame update
    21.     void Start()
    22.     {
    23.         ShipRB.maxAngularVelocity = 1f;
    24.  
    25.         bufferSize = 100;
    26.         forceBuffer = new float[bufferSize];
    27.         CBBuffer = new Vector3[bufferSize];
    28.         bufferIndex = 0;
    29.  
    30.         Vector3 oldCG = ShipRB.centerOfMass;
    31.         Vector3 oldCGWorld = ShipRB.worldCenterOfMass;
    32.         Vector3 offset = oldCGWorld - oldCG;
    33.        
    34.         Vector3 spherepos = CGSphere.transform.position;
    35.         Vector3 newCG = spherepos - offset;
    36.  
    37.         ShipRB.centerOfMass = newCG;
    38.  
    39.         Debug.Log("CoM: " + oldCG + "\nWCoM: " + oldCGWorld);
    40.         Debug.Log("Offset = "+offset);
    41.         Debug.Log("spherepos: " + spherepos + "\nnewCG: " + newCG);
    42.     }
    43.  
    44.     void FixedUpdate()
    45.     {
    46.         CVC.UpdateVisibility();
    47.         float displaced_volume = COBUpdate.CalculateBuoyancy();
    48.         float force = displaced_volume * 70;
    49.         ShipRB.drag = 1 + ((displaced_volume / 70000) * 9);
    50.  
    51.         //force magnitude inertia
    52.         bufferIndex = (bufferIndex + 1) % bufferSize;
    53.         forceBuffer[bufferIndex] = force;
    54.         float rollingAvg = 0;
    55.         foreach (float F in forceBuffer) { rollingAvg += F; }
    56.         rollingAvg /= bufferSize;
    57.  
    58.         //acting lever inertia
    59.         Vector3 CBWorld = CBSphere.transform.position;
    60.         Vector3 CBLocal = CBWorld - transform.position;
    61.         CBBuffer[bufferIndex] = CBLocal;
    62.         Vector3 rollingCBAvg = Vector3.zero;
    63.         foreach (Vector3 V in CBBuffer) { rollingCBAvg += V; }
    64.         rollingCBAvg /= bufferSize;
    65.  
    66.         Vector3 avgCB = transform.position + rollingCBAvg;
    67.         ShipRB.AddForceAtPosition((transform.up * rollingAvg), avgCB);
    68.  
    69.         clampPitch();
    70.  
    71.         Debug.Log("Force added to buffer: " + force + "\nApplied rolling avg force: " + rollingAvg);
    72.     }
    73.  
    74.     void clampPitch()
    75.     {
    76.         float maxAngVel = 0.015f;
    77.         float dampingFactor = 0.1f;
    78.         // Get the current angular velocity of the Rigidbody
    79.         Vector3 currentAngularVelocity = ShipRB.angularVelocity;
    80.  
    81.         // Apply damping to the z-axis
    82.         currentAngularVelocity.z *= (1f - dampingFactor * Time.fixedDeltaTime);
    83.  
    84.         // Limit the angular velocity in the z-axis
    85.         currentAngularVelocity.z = Mathf.Clamp(currentAngularVelocity.z, -maxAngVel, maxAngVel);
    86.  
    87.         // Assign the updated angular velocity back to the Rigidbody
    88.         ShipRB.angularVelocity = currentAngularVelocity;
    89.     }
    90.  
    91.     void Update()
    92.     {
    93.         Debug.Log("CURRENT VELOCITY = " + ShipRB.angularVelocity);
    94.     }
    95. }