In my previous blog posts, I talked about a project I was working on, a Katamari Damacy clone, called Clump Soul. What I chose to do was use a sphere for the play area instead of a plane, or the built in terrain that unity uses.
If you are here looking for instructions on creating a 3D world using unity’s built in terrain generator, let me tell you now, it is not built for that, and you will create a near endless amount of work for yourself trying to make it do this. If this does not deter you, check here, here or here. If that wont work for you, then use a smooth sphere as your terrain and just place your own grass and trees, or even create your own sphere with hills on it in Blender, for example. What I’m going to go over here is the problem of gravity and the player camera.
There are two main problems to work out when making a controllable character that will move across a spherical world. The spherical gravity and a controllable 3rd person camera that will orbit the player smoothly, while keeping them centered.
Problem #1: unity physics uses linear gravity, and has no spherical gravity built into it. What you need to do is have a point in space that everything is drawn towards, and treat that direction as downwards, so that each object also rotates as it travels around the source of gravity.
To the right is a visual example of what we want to achieve. The black orb is moving around the planet’s surface (or large ring around the planet which I am pretending is the surface), and is always pulled towards the center.
To achieve this, the first thing we need to do, is create the gravity. There are two types we can have, gravity that increases in strength as you get closer to the center of mass (great for a game featuring multiple celestial bodies, like KSP), and gravity that is applied at the same rate no matter the distance from the center of mass (like in Super Mario Galaxy). Picking the right one is very important, but the difference in the code is minimal, a diminishing gravity strength can be applied based on the distance between the object and the center of mass.
rigidbody.AddForce((planet.position - transform.position).normalized * acceleration);
What this code does is add force to the object this script is attached to. That force is in the direction of the ‘planet’ (get the gameobject’s transform for this), because we get a magnitude by subtracting the objects’ current point in space from the planets point in space. This is automatically normalized, and we then multiply it by acceleration (any number you put in, this will be how fast you are pulled towards the planet).
Now, getting the object to treat it as down (as if it is falling towards it).
What this does is rotate the object to face towards the planet, using the same method to get a magnitude as before for the direction we want to face. We also use the objects’ own up direction for the new up direction, this stops the object flipping upside down when we move to the bottom of the planet.
In my next post, I will cover the spherical planet 3rd person camera.
APA’s for spherical terrain links:
Spherical procedural terrain shader based on slope. (n.d.). Retrieved July 21, 2015.
Procedural planets. (n.d.). Retrieved July 21, 2015.