2D Skeleton Physics in Godot

Aeris
The BKPT
Published in
5 min readJan 3, 2023
Demo of mesh deformation animation and physics applied to Skeleton2Ds

Godot has built-in support for ragdoll physics on 3D skeletons out of the box. That is, one can call physical_bones_start_simulation() on a 3D skeleton and achieve the ragdoll effect without extra code.

In order to do the same in 2D, a little more work is necessary. This document presents one such method. This method requires the minimal amount of code and recreates a pendulum effect, similar to what Live2D implements. There are alternative approaches discussed under the section Alternative Approaches that a require more custom physics code.

Importing the 2D Model

Create the polygons presenting your 2D model. The node architecture should look like:

Node2D
Polygon2D
Polygon2D
Polygon2D
Polygon2D

Each Polygon2D presents a body part that can be animated. All parts that need to be independently animated should be given its own polygon.

Texture the Polygon2Ds

Set a teture on the Polygon2D. At this point, the texture will not show up. Click UV and draw a polygon boundary around the art asset to have the art show up.

At this point, you should be able to see the texture in the 2D preview.

Create the polygon meshes

Next, draw the internal polygons. This creates a mesh that we will map to bones. Use triangles. Rectangles and n-gons are also options.

UV editing menu

Create the Skeleton

Now we will create the skeleton. The skeleton should be a sister branch to the Node2D branch in the scene tree. The node architecture should look like so:

Skeleton2D
Bone2D
Bone2D
Bone2D

Each bone should be the parent to any bones it influences. For example, the neck bone should be the parent of the head bone because moving your neck also moves your head.
Assign the Skeleton2D to each Polygon2D.

Rig the Polygons

Now we will map the mesh to the bones. Go to the `Bones` tab (screenshot) and paint over the points that the bone should influence. For the best look, the bones should only effect points within it range. That is. it should not influence points beyond its length. Check out the ribbon’s UV as an example.

This concludes the rigging part of the tutorial. The next section is about applying physics to the Skeleton2d. Like I mentioned at the start, Skeleton2Ds do not come with built in physics. Instead, we will rely on RigidBody2Ds to simulation the physics and then apply the resulting movement to the Skeleton2D to make it seem as if the Skeleton2D has physics.

Simulating Pendulum Physics

We will do the following for each bone in your Skeleton2D:

Create a RigidBody2D. The origin of the RigidBody2D should be at the center of the bone it represents. The angle of the rigid body should match the top most parent bone of the Skeleton 2D. That is, in the top most Bone2D, go to Transform > Rotation degrees. Remember this value. Set the first (and only the first) RigidBody2D’s rotation_degrees to be this value.

If the RigidBody2D is supposed to be static (never moving), set its mode to "Static".

Add a CollisionShape2D as a child. The collision shape should match the shape of the bone are you trying to animate. Resive the collision shape to cover the bone and the Polygon2D. You can also use a CollisionPolygon2D if you need to use a custom shape to present the collision area.

Add a PinJoint2D as a child of the RigidBody2D.

Add a ColorRect as a child of the RigidBody2D. The color rect is our debugging visual to see what the RigidBody2D is doing. Resize and rotate the color rect to cover the same area as the collision shape.

Go to 7. Repeat for each Bone2D in the Skeleton2D.

At the end, your node structure should look like this:

Node2D
Polygon2D
Polygon2D
Polygon2D
Polygon2D
Skeleton2D
Bone2D
Bone2D
Bone2D
RigidBody2D1
CollisionShape2D
PinJoint2D
ColorRect
RigidBody2D2
CollisionShape2D
PinJoint2D
ColorRect
RigidBody2D3
CollisionShape2D
PinJoint2D
ColorRect

Final step is to take the physics simulation from the RigidBody2Ds and apply it to the Skeleton2D. You can do so via a script. Below is an example that applies the rotation_degrees from the RigidBody to the Skeleton2Ds.

onready var rigid_body_top: RigidBody2D = get_node("../PendulumSegment")
onready var rigid_body_mid: RigidBody2D = get_node("../RigidBody2DLong2")
onready var rigid_body_bottom: RigidBody2D = get_node("../RigidBody2DLong3")
onready var rigid_body_tassel: RigidBody2D = get_node("../RigidBody2DLong4")

onready var long_string_top = $LongStringTop
onready var long_string_mid = $LongStringTop/LongStringMid
onready var long_string_bottom = $LongStringTop/LongStringMid/LongStringBottom
onready var long_string_tassel = $LongStringTop/LongStringMid/LongStringBottom/LongStringTassel

func _physics_process(_delta):
long_string_top.rotation_degrees = rigid_body_top.rotation_degrees
long_string_mid.rotation_degrees = rigid_body_mid.rotation_degrees
long_string_bottom.rotation_degrees = rigid_body_bottom.rotation_degrees
long_string_tassel.rotation_degrees = rigid_body_tassel.rotation_degrees

And with that, we are done with set up. The remaining work is polishing the animation. You can do so by tuning the physics parameters.

Tuning the physics

Finally, when all of this is set up, you should see the skeleton move with the physics from the RigidBody2D. You will now need to tune the parameters to get the swinging motion to look as desired. Example YouTube video on tuning physics.

The primary properties you will tune are:

  • RigidBody
    - Weight
    - Gravity Scale
    - Linear > Damp
    - Angular > Damp
  • PinJoint2D
    - Softness
    - Bias

Other tips

  1. Right click an instanced node in the scene tree > select “Editable Children” to show the instance’s children. This will allow you to modify their properites. Tip from this video.
  2. There are 3 different kind of physics objects in godot: StaticBody, KineticBody and RigidBody. See this Godot tutorial for more information. You can mix and match the different types of physics bodies for different behavior.
  3. You can name the collision layers in the Project Settings. The layer names are displayed if you click the ellipses next to the collision layers in the Inspector. Link to Godot's tutorial.

Alternative Approaches

You can write your own pendulum physics instead of relying on RigidBody2Ds to calculate the movement. You can apply the calculated rotation and position to the Skeleton2D much like what was done above.

References

--

--

Aeris
The BKPT

Will probably use this blog to write about video games.