Skip to main content
Version: 5.x
Supported on
Snapchat
Camera Kit Android
This feature may have limited compatibility and may not perform optimally.
Camera Kit iOS
This feature may have limited compatibility and may not perform optimally.
Camera Kit Web
This feature may have limited compatibility and may not perform optimally.

Character Controller

The Character Controller Component is a modular, customizable movement system designed to support various gameplay formats, including third-person, first-person, side-scroller, and top-down style experiences. It provides a non-physics-based movement model with optional physics interactions, allowing for smooth, responsive controls without physics body dependencies. The Character Controller is designed for compatibility with Bitmoji 3D and custom characters.

Key Features

  • Multiple control schemes: Joystick or manual API control.
  • Physics integration: Collision detection, ground checking, gravity.
  • Animation support: Optional Idle and movement animations with speed thresholds.
  • Axis constraints: Lock movement along specific axes.
  • Sprint: Configurable sprint speeds and controls.

Usage


To use the Character Controller:

  1. Go to the Asset Library in Lens Studio and search for Character Controller in the Custom Components section.
  2. Click Install. The component will be added to the Asset Browser.
  3. Drag the Character Controller component into the scene or add it to an empty scene object.

Character's scale and position will not be changed in runtime by updating Transform. To change position, use setPosition() API instead.

  1. Add the Bitmoji 3D component to the same scene object.

Animation Setup: Make sure Adapt to Mixamo is enabled on the Bitmoji 3D component for animation support.

  1. In the Input Control section of the component inspector, set the Tracking Camera to a Camera object for the Joystick location.
  1. Adjust the movement settings to customize how your character responds to input.

Ground Setup: By default, Ground Is Zero is enabled in the Physics settings creating an infinite floor plane as a ground surface. Toggle this off to create an environment with custom ground surfaces.

  1. Add Physics Body and Physics Collider objects to the scene to create an environment for your character to interact with.

Physics Objects: Use objects with a Physics Body Component to create movable objects. Use objects with a Physics Collider Component for immovable objects (walls, grounds, platforms).

Character Controller supports only 1 Physics World Component in the project for proper collision handling.

Component Inputs

NameTypeDescription
Tracking CameraCameraCamera which renders character controller.
Move SpeednumberControls how fast the character moves.
Sprint SpeednumberControls how fast the character runs.
AccelerationnumberDetermines how quickly the character reaches full speed.
DecelerationnumberDefines how quickly the character slows down when input stops.
Min Move DistancenumberDefines the smallest movement distance before applying updates.
Auto Face Movement DirectionnumberDetermines if the character automatically rotates to match the movement direction.
Rotation SmoothingnumberDefines how smoothly the character rotates towards movement direction, from 0 to 1.
Input Control TypeNone | JoystickIf None is selected, user can move character controller manually with move(direction: vec3): void API. If joystick is enabled character will be moved using joystick.
Joystick PositionFree | Left | Right | CustomSets position of joystick. If Free is selected, joystick appears each time when user touches screen in that position.
Interactive AreaSceneObjectParent of joystick in case Custom is selected for joystickPosition. Should have ScreenTransform.
Joystick ParentSceneObjectParent of joystick in case Custom is selected for joystickPosition. Should have ScreenTransform.
SensitivitynumberAdjusts how responsive joystick input is.
Dead ZonenumberSize of the central region around the stick's neutral position where small movements are ignored to prevent unintended input.
Render OrdernumberRender order of joystick.
Lock X AxisbooleanDisables movement along the X axis.
Lock Y AxisbooleanDisables movement along the Y axis.
Lock Z AxisbooleanDisables movement along the Z axis.
Ground Check DistancenumberDefines how far the system looks below and above the character to detect ground.
Slope LimitnumberLimits movement on steep inclines to prevent unnatural climbing.
Step HeightnumberMaximum step height when climbing a step.
Ground Is ZerobooleanEnables a virtual ground plane at Y = 0 for simplified grounding behavior without requiring floor colliders.
Show ColliderbooleanMakes character controller collider visible.
Collider HeightnumberLength of capsule.
Collider RadiusnumberRadius of capsule.
Collider Centervec3Offset of capsule.
Animation AssetAnimationAssetAnimation asset for specified animation state.
Playback SpeednumberPlayback speed of specified animation state.
Min Character SpeednumberMinimum speed of character to trigger specified animation state.

Component API

NameDescription
move(direction: vec3): voidMoves the character in the specified direction. Y value will be ignored. To use this API to set character direction manually, please set Input Control Type to None.
stopMovement(): voidImmediately stops character movement.
setPosition(position: vec3): voidTeleports the character to a specific world position.
getPosition(): vec3Returns the current world position of the character.
setRotation(rotation: quat): voidSets the character's facing rotation. Will rotate character only around y axis.
getRotation(): quatGets the character's current rotation.
getDirection(): vec3Returns the current movement direction.
getVelocity(): vec3Returns the character's current velocity vector.
setSprintEnabled(enabled: boolean): voidIf true, enables sprinting speed, disables otherwise.
isSprinting(): booleanReturns true if sprint is currently active.
setMoveSpeed(speed: number): voidSets the character's base movement speed.
getMoveSpeed(): numberReturns the current base movement speed.
setSprintSpeed(speed: number): voidSets the character's sprint speed.
getSprintSpeed(): numberReturns the current sprint speed.
isGrounded(): booleanReturns true if the character is currently grounded.
isMoving(): booleanReturns true if the character is currently moving.
setAutoFaceMovement(enabled: boolean): voidEnables or disables auto-facing toward movement direction.
getAutoFaceMovement(): booleanReturns whether auto-facing movement is enabled.
setAcceleration(value: number): voidSets the acceleration value.
getAcceleration(): numberReturns the acceleration value.
setDeceleration(value: number): voidSets the deceleration value.
getDeceleration(): numberReturns the deceleration value.
setLockXAxis(enabled: boolean): voidEnables or disables movement along the X axis.
getLockXAxis(): booleanReturns whether movement along the X axis is currently locked.
setLockYAxis(enabled: boolean): voidEnables or disables movement along the Y axis.
getLockYAxis(): booleanReturns whether movement along the Y axis is currently locked.
setLockZAxis(enabled: boolean): voidEnables or disables movement along the Z axis.
getLockZAxis(): booleanReturns whether movement along the Z axis is currently locked.
setShowCollider(value: boolean): voidIf true is set character's collider is visible.
getShowCollider(): booleanReturns whether character's collider is visible.

API Events

Event NameTypeDescription
onCollisionEnterevent1<CollisionEnterEventArgs, void>Triggered when character starts colliding with another collider.
onCollisionStayevent1<CollisionEnterEventArgs, void>Triggered while character remains in collision.
onCollisionExitevent1<CollisionEnterEventArgs, void>Triggered when character exits a collision.
onOverlapEnterevent1<OverlapEnterEventArgs, void>Triggered when character enters an overlap volume.
onOverlapStayevent1<OverlapEnterEventArgs, void>Triggered while character remains in overlap volumes.
onOverlapExitevent1<OverlapEnterEventArgs, void>Triggered when character exits an overlap volume.

Moving the Character Toward Touch Position

Use the following example to move the character toward the most recent screen touch position.

Make sure that Input Control Type on the Character Controller is set to None, otherwise the call to move() will be ignored.

// Move the character towards the most recent touch position on the screen.

//@input Component.Camera camera;
//@input Component.ScriptComponent characterController
//@input float speed = 25
//@input float minDist = 25

let targetPos = null;

script.createEvent('UpdateEvent').bind(() => handleUpdate());
script.createEvent('TouchStartEvent').bind((e) => handleTouch(e));
script.createEvent('TouchMoveEvent').bind((e) => handleTouch(e));

function handleUpdate() {
if (targetPos) {
const charPos = script.characterController
.getTransform()
.getWorldPosition();
let offset = targetPos.sub(charPos);
offset.y = 0;

if (offset.length <= script.minDist) {
script.characterController.stopMovement();
targetPos = null;
} else {
const movement = offset
.normalize()
.uniformScale(script.speed * getDeltaTime());
script.characterController.move(movement);
}
}
}

function handleTouch(touchEvent) {
let screenPos = touchEvent.getTouchPosition();
let startPos = script.camera.screenSpaceToWorldSpace(
screenPos,
script.camera.near
);
let endPos = script.camera.screenSpaceToWorldSpace(
screenPos,
script.camera.far
);

let probe = Physics.createGlobalProbe();
probe.rayCast(startPos, endPos, (hit) => {
if (hit) {
targetPos = hit.position;
}
});
}

Testing on Device

To preview your Lens in Snapchat, follow the Pairing to Snapchat guide.

Was this page helpful?
Yes
No