Skip to content

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

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.

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)
  • event CharacterMoverNodeEvent|string
  • handler fun(value: any, source: CharacterMoverNode)

Returns integer id Connection id for disconnect

Reads an Inspector property by its path (vectors and colours as tables); “script.” reads a field of the node’s script.

local value = self.node:get_property("radius")
  • path CharacterMoverNodeProperty|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.” a field of the node’s script.

self.node:set_property("radius", 1.5)
  • path CharacterMoverNodeProperty|string
  • value any
  • y? 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? number Defaults 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") * 200

Returns 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)
  • vx number
  • vy number

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 * dt

Returns 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)
  • scale number

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 end

Returns boolean

Was the character touching a wall after the last move?

if self.node:character_is_on_wall() then vy = math.min(vy, 60) end

Returns 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 end

Returns 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.1

Returns 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"))
  • dirX number Horizontal direction (-1.0 to 1.0), times the node’s max speed
  • jump? boolean Whether 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 end

Returns 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)
  • speed number

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)
  • speed number
{
"type": "CharacterMoverNode",
"name": "CharacterMover",
"position": [
0,
0
],
"properties": {
"radius": 14,
"height": 28,
"maxSpeed": 240
}
}