Spherical Gravity in Unity
by Toys of Hendrik
Spherical gravity, you know that ? A game when the player walking on the spherical world like Super Mario Galaxy, Crash Course, or what else ?
Ya, that’s a spherical world is. Need an unusual gravity when we worked with unity and should make it first. There are several tutorial about this when you ask to Sir Google or maybe Uncle Youtube for it. But you’ll see the different here soon I hope.
So after looking around about
a weeks two days and found here, I make it for our upcoming game for the next two years maybe. Then I decide to make a tutorial about how player can walk more than one spherical world with following the weird steps bellow.
1. Preparing The Sphere
And the first thing, we should set the first world by adding a big sphere with GameObject –> 3D Object –> Sphere. Then make it big and center to the world by changing the position and rotation to zero (0) at all or you can see my transform Inspector.
And will be look like this when you decide to see the Game and Scene.
2. Standing Player
So we just need a simple mesh which can represent a player. Let’s make a Capsule with GameObject –> 3D Object –> Capsule. Place it above the big Sphere.
Add a rigidbody component inside the player.
3. The Gravity
For the gravity, we need a two hilarious script. One is for the sphere which is a main gravity and the other one is for object which want to attach to it. And we should make the first script like below (for Sphere, the script name is GravityAttractor.cs and maybe this is taking so long).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | using UnityEngine; using System.Collections; public class GravityAttractor : MonoBehaviour { public float gravity = -10; public void Attract(Transform body) { Vector3 gravityUp = (body.position - transform.position).normalized; Vector3 bodyUp = body.up; body.rigidbody.AddForce(gravityUp * gravity); Quaternion targetRotation = Quaternion.FromToRotation(bodyUp, gravityUp) * body.rotation; body.rotation = Quaternion.Slerp(body.rotation, targetRotation, 50 * Time.deltaTime); } } |
The float gravity variable is a minus value because another object which attach to it will pulling down. The next line is Attract method which have a ransform parameter called body. Attach this script to the Sphere.
The second script is for a player called GravityBody.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | using UnityEngine; using System.Collections; public class GravityBody : MonoBehaviour { public GravityAttractor attractor; private Transform myTransform; void Awake() { attractor = Object.FindObjectOfType<GravityAttractor>(); } void Start () { rigidbody.constraints = RigidbodyConstraints.FreezeRotation; rigidbody.useGravity = false; myTransform = transform; } void Update () { attractor.Attract(myTransform); } } |
Firstly, the script will help you to find object which have GravityAttractor attached inside automatically. Because the player have a rigidbody, the script will do some modification like uncheck the useGravity, freezing rotation. And the last is the player always linking the attractor from Sphere by Update method. Attach the script inside Player.
When you click Play, you’ll see the player is pulling down to the sphere like there is a magnet inside there.
4. Player can Move
Don’t want to see the player just standing there ? You can add a keyboard input event by making a new script called PlayerMove.cs. And the player can move as you wish.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | using UnityEngine; using System.Collections; public class PlayerMove : MonoBehaviour { public float moveSpeed = 10; public Vector3 moveDir; void Update () { moveDir = new Vector3(Input.GetAxisRaw("Horizontal"), 0, Input.GetAxisRaw("Vertical")).normalized; } void FixedUpdate() { rigidbody.MovePosition(rigidbody.position + transform.TransformDirection(moveDir) * moveSpeed * Time.deltaTime); } } |
We are using two different Update method right now. The Update() method is for getting the value of Horizontal and Vertical Axis, then getting their values, the FixedUpdate() will execute the Player’s transformation like moving front, back, left, or right. If you Want to know more about the difference between Update and FixedUpdate, you may look here. Next, add this script inside Player.
5. Another World
Another world means the player can walk in more than one sphere. In this case, you must add more function in GravityBody.cs script. We add OnCollisionEnter which the player can move to another sphere by touching or detect another Sphere collision. Just edit the GravityBody.cs script.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | using UnityEngine; using System.Collections; public class GravityBody : MonoBehaviour { public GravityAttractor attractor; private Transform myTransform; void Awake() { attractor = Object.FindObjectOfType<GravityAttractor>(); } void Start () { rigidbody.constraints = RigidbodyConstraints.FreezeRotation; rigidbody.useGravity = false; myTransform = transform; } void Update () { if(attractor == null){ attractor = Object.FindObjectOfType<GravityAttractor>(); } attractor.Attract(myTransform); } void OnCollisionEnter(Collision collision) { if(collision.gameObject.tag == "SphereGravity"){ attractor = collision.collider.GetComponent<GravityAttractor>(); } } } |
Oh sorry, we also add the checking line on the Update method, if the attractor is null than find another attractor object. Don’t forget to give a “SphereGravity” tag on the new Sphere.
Okay, I think it’s enough. Sorry if I’m not adding the video but I hope this video is represent enough.
P.S. : The browny sphere and the dark blue sky are from unity3d standart asset, use it by your own creation.