Search Unity

  1. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Why does Rigidbody 3d not have a gravity scale?

Discussion in 'Physics' started by ArachnidAnimal, Nov 10, 2016.

Thread Status:
Not open for further replies.
  1. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,727
    The rigidbody 2d has a gravity scale to affect falling acceleration.
    The rigidbody 3d does not have this.
    I have many rigidbody 3d which I would like to fall at different speeds. It seems the simplest way would be to assign a gravity scale and let the game engine/physics system control this.
    Other game engines have this functionality, but not Unity.
    Does anyone know why this is? What is the work-around to this limitation?
    This has been puzzling me for a while now.

    Thanks.
     
  2. Edy

    Edy

    Joined:
    Jun 3, 2010
    Posts:
    2,477
    2D physics and 3D physics use different engines, Box2D and PhysX respectively. Thus, the features and implementation are different.

    For 3D physics, the best workaround is to disable "Use Gravity" in the rigidbody and implement gravity by scripting. This simple component provides you a custom gravity scale per object:

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. [RequireComponent(typeof(Rigidbody))]
    4. public class CustomGravity : MonoBehaviour
    5.     {
    6.     // Gravity Scale editable on the inspector
    7.     // providing a gravity scale per object
    8.  
    9.     public float gravityScale = 1.0f;
    10.  
    11.     // Global Gravity doesn't appear in the inspector. Modify it here in the code
    12.     // (or via scripting) to define a different default gravity for all objects.
    13.  
    14.     public static float globalGravity = -9.81f;
    15.  
    16.     Rigidbody m_rb;
    17.  
    18.     void OnEnable ()
    19.         {
    20.         m_rb = GetComponent<Rigidbody>();
    21.         m_rb.useGravity = false;
    22.         }
    23.  
    24.     void FixedUpdate ()
    25.         {
    26.         Vector3 gravity = globalGravity * gravityScale * Vector3.up;
    27.         m_rb.AddForce(gravity, ForceMode.Acceleration);
    28.         }
    29.     }
     
    Last edited: Nov 10, 2016
  3. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,727
    OK thanks. This works good. Another thing I did was play around with the drag. Increasing the drag seems to produce the desired results.
     
  4. gerrva_unity

    gerrva_unity

    Joined:
    Aug 12, 2019
    Posts:
    1
    saved my life :)
     
    leozhang1 likes this.
  5. bekthedev

    bekthedev

    Joined:
    Jul 12, 2020
    Posts:
    3
    thank you very much
     
    leozhang1 likes this.
  6. nerz89

    nerz89

    Joined:
    Aug 4, 2021
    Posts:
    1
    Man, thanks for the script you posted earlier. Definitely a life saver.
     
  7. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    I would not mess around with drag in this case.
    Just turn off gravity for particular object and add custom gravity component.

    AddForce(Physics.gravity * scale, ForceMode.Acceleration)
     
  8. r31o

    r31o

    Joined:
    Jul 29, 2021
    Posts:
    460
    Hmmmm. ¿Scale? rigidbody.mass will be better if not then, I guess will be scale * scale * scale.
     
  9. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    What the hell are you talking about ?
     
  10. r31o

    r31o

    Joined:
    Jul 29, 2021
    Posts:
    460
    Oh, I'm an idiot.
    I dont know what I was thinking when I wrote that. I was kinda confused.
    I want to end this post with the solution.
    So, I guess the solution for @ArachnidAnimal is this little script:
    Code (Csharp):
    1. using UnityEngine;
    2.  
    3. [RequireComponent(typeof(Rigidbody))]
    4. public class GravityScale : MonoBehaviour
    5. {
    6.     public float gravityScale = 1f; //The gravity scale
    7.     Rigidbody rb;
    8.    
    9.     void Start()
    10.     {
    11.         rb = GetComponent<Rigidbody>();
    12.     }
    13.  
    14.     void FixedUpdate()
    15.     {
    16.         rb.AddForce(Physics.gravity * gravityScale * Time.fixedDeltaTime, ForceMode.Acceleration) //It has to be FixedUpdate, because it applies force to the rigidbody constantly.
    17.     }
    18. }
    This should work.
     
  11. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,065
    No it should not.
    Physics.gravity is already an acceleration, there is no need to multiply it by fixedDeltaTime.
     
  12. r31o

    r31o

    Joined:
    Jul 29, 2021
    Posts:
    460
    Sorry, just I didn't knew it.
    Will work without the fixedDeltaTime.
     
  13. Taka33Taka33

    Taka33Taka33

    Joined:
    May 15, 2022
    Posts:
    16
    For clarification:
    Code (CSharp):
    1.     using UnityEngine;
    2.    
    3.     [RequireComponent(typeof(Rigidbody))]
    4.     public class GravityScale : MonoBehaviour
    5.     {
    6.         public float gravityScale = 1f; //The gravity scale
    7.         Rigidbody rb;
    8.      
    9.         void Start()
    10.         {
    11.             rb = GetComponent<Rigidbody>();
    12.         }
    13.    
    14.         void FixedUpdate()
    15.         {
    16.             rb.AddForce(Physics.gravity * gravityScale , ForceMode.Acceleration) //It has to be FixedUpdate, because it applies force to the rigidbody constantly.
    17.         }
    18.     }
    19.  
     
    Weebazaki, DrZwieback and chzwhz like this.
  14. leorehman333

    leorehman333

    Joined:
    Sep 4, 2021
    Posts:
    2
    Thanks brother
     
Thread Status:
Not open for further replies.