Character Mover
Kinematic character controller with smooth velocity integration, slope climbing, and ground snapping.
Type: CharacterMoverNode · Category: Physics & Collision · Also found as: charactermover, character_mover
Properties
Section titled “Properties”| Property | Type | Default | Description |
|---|---|---|---|
radius |
number | 14 |
Capsule radius (px). Range 2 to 200. |
height |
number | 28 |
Capsule height (px). Range 2 to 400. |
velocity |
vec2 | (0, 0) |
Velocity now (px/s). Range -1000 to 1000. Runtime state: read-only, not saved. |
targetSpeedX |
number | 0 |
Horizontal speed the built-in movement accelerates to (px/s). Range -600 to 600. Runtime state: read-only, not saved. |
maxSpeed |
number | 240 |
Top running speed (px/s). Range 10 to 1000. |
acceleration |
number | 1200 |
How quickly it reaches top speed (px/s²). Range 10 to 5000. |
jumpSpeed |
number | 320 |
Upward speed of a jump (px/s). Range 10 to 1200. |
gravityScale |
number | 1 |
Multiplies the world’s gravity for the character. Range 0 to 5. |
pushLimit |
number | 500 |
Most push per step from overlapping bodies (px/s; 0 = unlimited). Range 0 to 1000. |
clipVelocity |
boolean | true |
Remove velocity into walls and floors it hits (slide along them). |
enableKeyboardInput |
boolean | true |
Built-in movement: the move / jump input actions drive it. |
isGrounded |
boolean | false |
Standing on something now. Runtime state: read-only, not saved. |
categoryLayers |
flags: Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, Layer7, Layer8, Layer9, Layer10, Layer11, Layer12 … |
[Layer1] |
Collision layers this object is on (names in Project Settings > Physics). |
maskLayers |
flags: Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, Layer7, Layer8, Layer9, Layer10, Layer11, Layer12 … |
[Layer1, Layer2, Layer3, Layer4, Layer5, Layer6, Layer7, Layer8, Layer9, Layer10, Layer11, Layer12, Layer13, Layer14, Layer15, Layer16] |
Collision layers this object collides with. |
debugColor |
color | #facc15ff |
Colour of the collider outline drawn with Show Bounds & Colliders (and the game’s debug draw). |
controlMode |
enum: BuiltIn, Script |
BuiltIn |
Built-in movement, or Script: the script moves it (character_move_and_slide). |
Plus the common properties every node has.
Lua methods
Section titled “Lua methods”Call them on the node (self.node in its script, or self.node:get_node("path")). Every node also has the Node methods.
CharacterMoverNode:connect(event, handler)
Section titled “CharacterMoverNode:connect(event, handler)”Connects a handler to one of this node’s events: collision_started (Contact with another body began), collision_ended (Contact with another body ended); the tree events; custom ones.
self.node:connect("collision_started", function(value, source) Log.info("collision_started") end)eventCharacterMoverNodeEvent|stringhandlerfun(value:any, source: CharacterMoverNode)
Returns integer id Connection id for disconnect
CharacterMoverNode:get_property(path)
Section titled “CharacterMoverNode:get_property(path)”Reads an Inspector property by its path (vectors and colours as tables); “script.
local value = self.node:get_property("radius")pathCharacterMoverNodeProperty|string
Returns any
CharacterMoverNode:set_property(path, value, y)
Section titled “CharacterMoverNode:set_property(path, value, y)”Sets an Inspector property by its path: vectors as {x, y} or x, y; colours as {r, g, b[, a]} 0..1 or “#rrggbb[aa]”; enums by name; “script.
self.node:set_property("radius", 1.5)pathCharacterMoverNodeProperty|stringvalueanyy?number
CharacterMoverNode:character_move_and_slide(dt)
Section titled “CharacterMoverNode:character_move_and_slide(dt)”Moves by the velocity (x dt), sliding along whatever it touches; the velocity loses the part going into surfaces. Updates the floor / wall / ceiling state. Switches the node to Script mode.
local collided = self.node:character_move_and_slide(dt)dt?numberDefaults to the frame’s delta time
Returns boolean collided
CharacterMoverNode:character_get_velocity()
Section titled “CharacterMoverNode:character_get_velocity()”Gets the velocity in pixels per second (+y is down).
local vx, vy = self.node:character_get_velocity(); vx = Input.get_axis("left", "right") * 200Returns number vx, number vy
CharacterMoverNode:character_set_velocity(vx, vy)
Section titled “CharacterMoverNode:character_set_velocity(vx, vy)”Sets the velocity in pixels per second (+y is down).
self.node:character_set_velocity(vx, -350)vxnumbervynumber
CharacterMoverNode:character_get_gravity()
Section titled “CharacterMoverNode:character_get_gravity()”Gets the gravity acting on the character: world gravity x its gravity scale.
local gx, gy = self.node:character_get_gravity(); vy = vy + gy * dtReturns number gx, number gy
CharacterMoverNode:character_set_gravity_scale(scale)
Section titled “CharacterMoverNode:character_set_gravity_scale(scale)”Sets the multiplier of the world gravity for this character.
self.node:character_set_gravity_scale(0.5)scalenumber
CharacterMoverNode:character_is_on_floor()
Section titled “CharacterMoverNode:character_is_on_floor()”Was the character standing on a floor after the last move?
if self.node:character_is_on_floor() and Input.is_action_pressed("jump") then vy = -350 endReturns boolean
CharacterMoverNode:character_is_on_wall()
Section titled “CharacterMoverNode:character_is_on_wall()”Was the character touching a wall after the last move?
if self.node:character_is_on_wall() then vy = math.min(vy, 60) endReturns boolean
CharacterMoverNode:character_is_on_ceiling()
Section titled “CharacterMoverNode:character_is_on_ceiling()”Was the character touching a ceiling after the last move?
if self.node:character_is_on_ceiling() then vy = 0 endReturns boolean
CharacterMoverNode:character_get_floor_normal()
Section titled “CharacterMoverNode:character_get_floor_normal()”The floor’s normal (0, -1 on flat ground; tilted on slopes).
local nx, ny = self.node:character_get_floor_normal(); local on_slope = math.abs(nx) > 0.1Returns number nx, number ny
CharacterMoverNode:character_get_wall_normal()
Section titled “CharacterMoverNode:character_get_wall_normal()”The wall’s normal (points away from the wall).
local nx, ny = self.node:character_get_wall_normal(); self.node:character_set_velocity(nx * 250, -300)Returns number nx, number ny
CharacterMoverNode:character_get_last_motion()
Section titled “CharacterMoverNode:character_get_last_motion()”How far the last move actually went.
local dx, dy = self.node:character_get_last_motion(); self.distance = self.distance + math.abs(dx)Returns number dx, number dy
CharacterMoverNode:character_set_control_mode(mode)
Section titled “CharacterMoverNode:character_set_control_mode(mode)”“script”: the script moves it with character_move_and_slide; “builtin”: it moves itself.
self.node:character_set_control_mode("builtin")mode"script"|"builtin"
CharacterMoverNode:character_move(dirX, jump)
Section titled “CharacterMoverNode:character_move(dirX, jump)”BuiltIn mode: steers the character horizontally and jumps if grounded.
self.node:character_move(Input.get_axis("left", "right"), Input.is_action_pressed("jump"))dirXnumberHorizontal direction (-1.0 to 1.0), times the node’s max speedjump?booleanWhether to jump if grounded
CharacterMoverNode:character_is_grounded()
Section titled “CharacterMoverNode:character_is_grounded()”Same as character_is_on_floor().
if self.node:character_is_grounded() then self.coyote = 0.1 endReturns boolean
CharacterMoverNode:character_set_speed(speed)
Section titled “CharacterMoverNode:character_set_speed(speed)”BuiltIn mode: sets the maximum horizontal run speed.
self.node:character_set_speed(220)speednumber
CharacterMoverNode:character_set_jump_speed(speed)
Section titled “CharacterMoverNode:character_set_jump_speed(speed)”BuiltIn mode: sets the jump speed.
self.node:character_set_jump_speed(400)speednumber
In a scene file
Section titled “In a scene file”{ "type": "CharacterMoverNode", "name": "CharacterMover", "position": [ 0, 0 ], "properties": { "radius": 14, "height": 28, "maxSpeed": 240 }}