There’s some awesome level design
in Super Mario Galaxy where you can walk around planets with their
own gravitational attraction, letting you walk upside down and
travel from one planet to another. By taking advantage of Godot’s
powerful physics options creating this style of 3D planets
is way easier than you would expect. This mechanic has two parts: The planet that applies gravity to the
character when it’s near one of them. The character that moves around
planets and gets attracted to them. For the character we’ll use a RigidBody to rely
on Godot’s built-in physics as much as possible. For the planet we need two key nodes:
a static body to walk on and an Area. The Area handles all the complicated math
involved in attracting the character. For the planet we make a StaticBody
node with a spherical MeshInstance and a matching sphere CollisionShape. We then add an Area and a sphere CollisionShape
for the area of gravity. You want to make it larger than the MeshInstance: this is the area in
which the character will fall towards the planet. There are a few properties to tweak on the Area: We need to enable gravity point, making the area
act as the center of gravity for our character. The gravity_vec property determines
the position of the center of gravity, so let’s set it to 0 0 0 to center it. Change the space override property to replace. It makes it so any body that enters the
area uses it as its source of gravity. Lastly, you can increase the strength
of gravity with the gravity property. I added two of these planets to a scene
with a camera capturing both. I positioned it so the gravity areas overlap. This way, the
character can jump from one planet to the other. We need a capsule collision shape
and a mesh for our player’s body. Thankfully, we have a body mesh with
animations already made and ready to go. Now we need to set a few
properties for the RigidBody: Using the character mode keeps the character
upright, preventing unwanted rotations. To detect collisions, we enable contact
monitor and set contacts reported to at least 1. This detects when the
player is standing on the floor. Moving the character along the planet’s
surface comes with two little challenges: We need the player’s controls
to be relative to the character. And we need to orient the character
to the planet as it moves. All the player’s movement happens in the
_integrate_forces() virtual function, which is unique to rigid bodies. Like in 2D, we first calculate
the player’s input direction. We then use the xform function to turn the
vector to face the same way as the model. Xform is a shorthand for transform. It applies an object’s transform to a
vector or another transform. We move the player in this direction
with the RigidBody’s add_force function. To align the model with the
movement, we calculate a Basis. That’s a matrix with three vectors
representing an orientation in space. We already have two of the three
vectors: the gravity, which we get from the function’s state parameter, and the
move direction xformed to the character model. We calculate the third using the
vector cross product. The function returns a vector perpendicular
to the two we pass as inputs. The target character alignment is a
basis made of those three vectors. The final step is to use the spherical lerp
function to have the character turn smoothly. To jump, we first check that the character is
on the floor. The contact monitoring we set earlier can tell us if we are
in contact with a surface. To ensure we’re on the floor, we loop over all
the contact points and their normal every frame. The normal is the direction
straight out from the surface. By comparing it to the gravity, we
can tell if that surface is the floor. To compare the angle of vectors, we use
an operation called the dot product. The more they align, the closer the returned value is to 1. When the two vectors are
perpendicular, the value is close to 0. If the dot product is, say, greater than 0.5
then we can assume we are walking on some planet. When that’s the case and the player wants to jump, we apply an impulse in the
opposite direction of gravity. And we’re all set with a character that can run
around a 3D planet and even jump between them! Right now we’re on Kickstarter to fund
Learn to Code from Zero, with Godot. We’ve been working for months to make the
course we wish we had back when we got started. It makes for a great gift to a
loved one who’d like to become a game developer and helps the Godot community. Thanks to the funding, we’re
making a free and open-source app for everyone to learn Godot’s
GDScript right in their browser. You can back the campaign to make this a
reality, get the course at a lower price, but you only have until October 31. So check the campaign now on Kickstarter.