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
Setup
- Add an SgPlayer scene object (feet at the Transform origin).
- Add an SgCamera as a child (or elsewhere) and assign it to the Camera field.
- Optionally add / link an SgMesh and set Idle / Walk / Run clip names.
- Tune capsule size, speeds, and perspective (First person / Third person).
- Configure Input devices (Enable keyboard / mouse / gamepad) and bindings.
- 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,landedstartWalking,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.codestrings (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
Create a new player controller object in the scenegraph.
Parameters
selfoptions(table): A table of options to fill the parametersparent(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
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
Return whether built-in input is enabled.
Returns
boolean
setPerspective
Set camera perspective.
Parameters
perspective(string): one of SgPlayer.Perspective
getPerspective
Get the current camera perspective.
Returns
string: of SgPlayer.Perspective
isOnGround
Return true if the character is standing on ground.
Returns
boolean
getHorizontalSpeed
Return horizontal movement speed (XZ).
Returns
number
getVelocity
Return the last known velocity from the character controller.
Returns
table: with x, y, z
warp
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 |