Skip to content

SgPlayer

A no-code first- and third-person player controller backed by Bullet's btKinematicCharacterController. Place an SgPlayer in the scene, link an SgCamera (preferably as a child), and press Play.

Default bindings match common FPS/TPS controls (WASD + arrows, mouse look, Space jump, Shift sprint, standard gamepad axes/buttons). Every binding and device can be changed per player so split-screen and personal preference work without scripts.

Inherits from

SceneObject

Setup

  1. Add an SgPlayer scene object (feet at the Transform origin).
  2. Add an SgCamera as a child (or elsewhere) and assign it to the Camera field.
  3. Optionally add / link an SgMesh and set Idle / Walk / Run clip names.
  4. Tune capsule size, speeds, and perspective (First person / Third person).
  5. Configure Input devices (Enable keyboard / mouse / gamepad) and bindings.
  6. For mouse look, enable project Automatic pointer lock, or lock from a script.

In the editor a capsule wireframe (and forward arrow) shows the character volume when Always show helper is enabled. It is removed during play.

On play the player forces the linked camera to Free mode and activates it. Existing Follow / Look-at modes are restored when play stops.

Game events

SgPlayer emits locomotion events you can listen to with node:on:

  • jump, landed
  • startWalking, endWalking, startRunning, endRunning

See Node Game Events for payloads and examples.

Input & split-screen

Each SgPlayer has independent:

  • Enable keyboard / mouse / gamepad — turn devices on or off for that player
  • Gamepad index — which connected pad this player uses (0, 1, 2, …)
  • Keyboard codes — each binding is a Keys list of KeyboardEvent.code strings (same values as Keys). Add as many alternatives as you need; the old separate “alt” fields are gone.
  • Gamepad axes / buttons — numeric indices into the browser Gamepad API

Example: player 1 uses keyboard + mouse; player 2 uses only gamepad index 1:

local Keys = require 'engine/keys'

-- Player 2: gamepad only
player2.enableKeyboard = false
player2.enableMouse = false
player2.enableGamepad = true
player2.gamepadIndex = 1

-- Remap player 1 jump to E (and keep Space as an alternative)
player1.keyJump = { Keys.E, Keys.Space }

Scripting

Disable all built-in input when you want fully custom controls, or warp the player:

local SgPlayer = require 'engine/sceneobjects/sgplayer'

-- On a Behaviour attached to the player node:
function PlayerScript:init()
    self.player = self.node  -- SgPlayer
    self.player:setPerspective(SgPlayer.Perspective.FirstPerson)
end

function PlayerScript:update(dt)
    if self.player:isOnGround() then
        -- ...
    end
end

create

static create(self, options, parent)

Create a new player controller object in the scenegraph.

Parameters

  • self
  • options (table): A table of options to fill the parameters
  • parent (SceneObject): The parent scene object to add this to

Returns

  • Promise: promise which will resolve to the created object

Example

-- Options can be omitted. This example shows the defaults,
-- only specify the ones you want different.
SgPlayer.create({
    active = true,
    static = false,
    name = "",
    transform = Transform.new(),
    layers = {0},
    tags = {},
    rendered = true,
    camera = nil,
    mesh = nil,
    perspective = SgPlayer.Perspective.ThirdPerson,
    enableKeyboard = true,
    enableMouse = true,
    enableGamepad = true,
    gamepadIndex = 0,
    gamepadDeadzone = 0.2,
    keyMoveForward = { "KeyW", "ArrowUp" },
    keyMoveBack = { "KeyS", "ArrowDown" },
    keyMoveLeft = { "KeyA", "ArrowLeft" },
    keyMoveRight = { "KeyD", "ArrowRight" },
    keyJump = { "Space" },
    keySprint = { "ShiftLeft", "ShiftRight" },
    invertMouseY = false,
    gamepadMoveAxisX = 0,
    gamepadMoveAxisY = 1,
    gamepadLookAxisX = 2,
    gamepadLookAxisY = 3,
    gamepadJumpButton = 0,
    gamepadSprintButton = 7,
    invertGamepadLookY = false,
    radius = 0.3,
    height = 1.8,
    stepHeight = 0.35,
    maxSlope = 45,
    walkSpeed = 3.5,
    runSpeed = 6.5,
    jumpSpeed = 6,
    lookSensitivity = 0.15,
    pitchMin = -80,
    pitchMax = 80,
    eyeHeight = 1.6,
    cameraDistance = 4,
    cameraHeight = 1.5,
    cameraShoulderOffset = 0.4,
    cameraLag = 0,
    cameraFollowMovement = false,
    cameraCollisionAvoidance = true,
    cameraCollisionRadius = 0.25,
    cameraCollisionMargin = 0.05,
    cameraCollisionDamping = 0.1,
    idleAnimation = "",
    walkAnimation = "",
    runAnimation = "",
    walkSpeedThreshold = 0.2,
    runSpeedThreshold = 4
})

Properties

You can access these properties directly on the object (preferred), for example obj.active = true or local v = obj.active. The :get("propertyName") / :set("propertyName", value) methods also work, but prefer direct property access in examples and scripts.

Property Type Default Description
active Boolean true A Boolean attribute indicating whether the 3D object is active or not. When set to true, the object is considered active in the scene.
static Boolean false Marks the object as immovable during play. Static objects ignore transform changes at runtime and use a fixed physics collider with zero mass.
transform Transform Transform.new() Specifies the transformation properties of the 3D object, including its position, rotation, and scale in the scene.
layers Layers [0] Determines the layers the 3D object belongs to. Layers are used to organize objects in the scene for various purposes like rendering and interaction.
tags Tags [] A list of tags associated with the 3D object. Tags are used for categorizing and identifying objects for scripting and scene management.
rendered Boolean true When disabled, the object and its descendants are not drawn, but may still simulate physics or run scripts.
camera Node
SgCamera controlled by this player (first/third person). Prefer a child camera; falls back to the first child Camera if unset.
mesh Node
Optional SgMesh for the character body and locomotion animations. Falls back to the first child Mesh if unset.
perspective Enum Third person Camera perspective. First person places the camera at eye height; third person orbits behind the player. | Options: First person, Third person
enableKeyboard Boolean true When enabled, this player reads configured keyboard bindings. Disable for gamepad-only or other players in split-screen.
enableMouse Boolean true When enabled, pointer-lock mouse movement controls look. Disable for keyboard-only or gamepad-only players.
enableGamepad Boolean true When enabled, this player reads the configured gamepad index and axis/button bindings.
radius Float 0.3 Character capsule radius in world units.
height Float 1.8 Full character capsule height in world units (including hemispheres). Transform origin is at the feet.
alwaysShowHelper Boolean true Show a capsule wireframe helper in the editor. Helpers are never shown during play.
stepHeight Float 0.35 Maximum step height the character can climb.
maxSlope Float 45 Maximum walkable slope angle in degrees.
walkSpeed Float 3.5 Walking speed in units per second.
runSpeed Float 6.5 Sprint speed in units per second (Shift / gamepad trigger).
jumpSpeed Float 6 Upward jump speed for the kinematic character controller.
lookSensitivity Float 0.15 Mouse / stick look sensitivity.
pitchMin Float -80 Minimum look pitch in degrees.
pitchMax Float 80 Maximum look pitch in degrees.
eyeHeight Float 1.6 Camera height above the feet for first person and look-at target for third person.
cameraLag Float 0 Seconds of look follow lag (0 = instant). Higher values add inertia to camera rotation.
idleAnimation String
Clip name on the linked mesh for idle (optional).
walkAnimation String
Clip name on the linked mesh for walking (optional).
runAnimation String
Clip name on the linked mesh for running (optional).
walkSpeedThreshold Float 0.2 Horizontal speed above which the walk clip is used.
runSpeedThreshold Float 4 Horizontal speed above which the run clip is used.

setInputEnabled

setInputEnabled(enabled)

Enable or disable the built-in keyboard / mouse / gamepad input master switch. Per-device flags (EnableKeyboard / EnableMouse / EnableGamepad) still apply when this is true.

Parameters

  • enabled (boolean)

isInputEnabled

isInputEnabled()

Return whether built-in input is enabled.

Returns

  • boolean

setPerspective

setPerspective(perspective)

Set camera perspective.

Parameters

  • perspective (string): one of SgPlayer.Perspective

getPerspective

getPerspective()

Get the current camera perspective.

Returns

  • string: of SgPlayer.Perspective

isOnGround

isOnGround()

Return true if the character is standing on ground.

Returns

  • boolean

getHorizontalSpeed

getHorizontalSpeed()

Return horizontal movement speed (XZ).

Returns

  • number

getVelocity

getVelocity()

Return the last known velocity from the character controller.

Returns

  • table: with x, y, z

warp

warp(x, y, z)

Teleport the player to a world-space position (feet).

Parameters

  • x (number)
  • y (number)
  • z (number)

Enum: Perspective

Enumeration of camera perspectives for the player controller.

Field Name Description
FirstPerson string: first-person eye camera
ThirdPerson string: third-person orbit camera

Further reading