Alex’s Godot Character Movement Manifesto
You can find an example Godot Character Controller using move_and_collide
here
Motivation
- I spent a long time learning about and creating character controllers in Unity for Ballistic Zen
- Shifty’s Godot Character Movement Manifesto is a bit out of date
- I switched to Godot and had to learn a lot, again. I want to help others in my situation!
Context
- This manifesto is about first person character controllers
- Third person character controllers can do a lot with character animations and free-er camera movement
Built-in vs Custom Character Controllers, and a Philosophy on what to build
- Built-in character controllers will always have unworkable issues
- Built-in character controllers are intended for a wide audience to get movement working quickly
- There is no universal character controller
- If you care about movement, creating a custom character controller is inevitable
- There should be no expectation on game engine developers to provide a character controller that meets all your needs
- For what it’s worth, I think Godot should provide step functionality, but they don’t currently
- Character controller design is inextricably linked with the game environment
- If there are no steps in the game, don’t make a step function
- If there are no height changes in the game, don’t let the character move up and down
- There are more ignorable edge cases than you expect.
- Environmental work-arounds such as ramps instead of stairs are possible; they add load to level design, but make character controller development easier
- Don’t build a character controller in isolation from the environment it will inhabit
- Character controller development requires fast iteration; avoid engine or physics rewrites (if you’re not running your own)
- If the engine you are using has deep-rooted physics issues, prepare to compromise!
- Character controller development is complicated, but does not take that long once you know what you’re doing!
General Techniques
- Prefer (most to least) Cylinder > Cube > Capsule shape for collision detection
- Capsules reduce the demand for complicated slide algorithms but behave unreliably at platform edges
- A cube’s flat bottom creates reliable platform edge behaviour, and variability in closest wall distance based on wall angle is hardly noticable, but slide direction behaves unreliably where walls join
- A cylinder’s flat bottom creates reliable platform edge behaviour, and the curved edge creates reliable wall slide behaviour
- Prefer Shape casts over ray casts; ray casts can easily miss parts of the environment
- Steps can be handled by:
- (Simpler) Ignore collisions at the bottom of the controller, and force a minimum distance distance to the floor below; this has the disadvantage of causing slope slide behaviour to become very confusing; I do not recommend doing this if you have steep slopes in your game
- (More General) Perform additional tests “Up, forward, down” and use the results to potentially modify the final movement
- Blocking movement on slopes is tricky when multiple slopes intersect!
- Run physics at a fixed timestep; interpolate visually to prevent jitters
- See my Godot controller here - many techniques I use are appropriate for any character controller
Godot Specifics
- Physics nodes have been renamed since Shifty’s Manifesto. Example PR
- CharacterBody has
move_and_slide
and is intended for character bodies- CharacterBody does not have a step function, but one could be created using Physics Space State
- CharacterBody
move_and_slide
behaviour is suitable for simple geometry but is unreliable especially with complicated slopes
- RigidBody3D has
integrated_forces
and is intended for physics objections- I don’t believe it is possible to manually set an object position inside
integrated_forces
, so I don’t believe it is suitable for character controllers
- I don’t believe it is possible to manually set an object position inside
- StaticBody has
move_and_collide
, and is intended for custom behaviourmove_and_collide
and setting position manually allows creation of most desired behaviourmove_and_collide
performs automatic depentration which obfuscates some issues, and appears to have minor issues with vertical movement and slopes; but I nevertheless recommend it for most projects- AnimatableBody3D is a StaticBody that affects the environment, and could be used as a mostly drop in replacement. I have not tested this.
- IMPORTANT Godot physics is still buggy in Godot 4.0. Box collisions seem to work well, but Cylinder collisions are broken. Using Jolt is absolutely mandatory for custom character controller development.
- Jolt is non-deterministic; this means physics are not consistent - but physics are still predictable - there are no noticable downsides to movement using Jolt
- Depending on game mechanics (replays?) non-determinism might be a deal breaker - in this case fall back to default physics and the humble cube!
- See my Godot controller here to see an example of using
move_and_collide