Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Creating faux gravity for shapes other than a sphere

Discussion in 'Physics' started by jeremydulong, Aug 12, 2018.

  1. jeremydulong


    Nov 9, 2017
    I've implemented faux gravity by attaching the below Gravity Attractor script to a sphere object, and the Gravity Body script to my player. This works fine for moving around the surface of the sphere as if it were a planet, attracting the player to the center. However I now want to implement the same effect on a cylinder instead of a sphere, so that the player can move around the cylinder and up and down the long side as they wish. Right now the faux gravity is pulling the player towards the center of the cylinder because that's the center of the rigid body. How could I change this so the player is instead just pulled to the inside of the cylinder, not the center of the inside?

    Code (CSharp):
    1. public class GravityAttractor : MonoBehaviour {
    3.     public float gravity = -10;
    5.     public void Attract(Transform body){
    6.         Vector3 gravityUp = (body.position - transform.position).normalized;
    7.         Vector3 bodyUp = body.up;
    9.         body.GetComponent<Rigidbody>().AddForce(gravityUp * gravity);
    10.         Quaternion targetRotation = Quaternion.FromToRotation(bodyUp, gravityUp) * body.rotation;
    11.         body.rotation = Quaternion.Slerp(body.rotation, targetRotation, 50 * Time.deltaTime);
    12.     }
    14. }
    Code (CSharp):
    1. public class GravityBody : MonoBehaviour {
    3.     public GravityAttractor attractor;
    4.     private Transform myTransform;
    6.     void Start () {
    7.         Rigidbody body = GetComponent<Rigidbody>();
    8.         body.freezeRotation = true;
    9.         body.useGravity = false;
    10.         myTransform = transform;
    11.     }
    13.     void Update () {
    14.         attractor.Attract(myTransform);
    15.     }
    16. }
  2. Edy


    Jun 3, 2010
    This is an interesting geometry and vector math problem. You should split the space surrounding the cylinder in 5 zones, then figure out in which zone the player is located in, and apply a proper gravity to it.
    • Around the cylindrical surface: gravity towards the axis, perpendicularly to it.
    • Over each of the bases: gravity vertically towards the base.
    • The two intermediate areas between the each base and the body. These are the tricky parts. The gravity should be directed towards the circular edge of the base. This would produce a smooth gravity transition when the player walks from the cylindrical surface to the base.
    Apart from that, have in mind that you should apply forces and modifications to the rigidbody from FixedUpdate, not from Update. Otherwise, from Update you may end applying more or less force based on the varying frame rate.
  3. SparrowsNest


    Apr 6, 2017
    How about looking at the normal of what the player is standing on(or jumping above) and applying gravity in the negative normal direction?
  4. Edy


    Jun 3, 2010
    First you would need to determine "what the player is standing on (or jumping above)" with respecto to the cylinder. That would require some algorithm as the one I described.

    Also, looking at the normal alone wouldn't work when the player is neither above the side of the cylinder nor the bases.
    Last edited: Aug 16, 2018