terminalCode Example

CharacterController — capsule movement, ground checks, and velocity control

calendar_today May 5, 2026 schedule ~1 min read person patrickjr verified 50

CharacterController in s&box

CharacterController is a built-in s&box component for capsule-based movement. Unlike Rigidbody, you control velocity directly — the controller handles collision resolution, step climbing, and slope limits.

Component Properties

PropertyDescription
RadiusCapsule radius (default 16)
HeightCapsule height (default 64)
StepHeightMax step the controller can climb (default 18)
GroundAngleMax walkable slope in degrees (default 45)
AccelerationMovement acceleration
BouncinessVelocity preserved on collision (default 0.3)

First-Person Player Movement

CSHARP
public sealed class PlayerMovement : Component
{
    [RequireComponent] CharacterController Controller { get; set; }

    [Property] float MoveSpeed { get; set; } = 200f;
    [Property] float JumpForce { get; set; } = 300f;
    [Property] float Gravity   { get; set; } = 800f;

    Vector3 _velocity;

    protected override void OnUpdate()
    {
        var wishDir = new Vector3( Input.AnalogMove.x, Input.AnalogMove.y, 0 )
            .Normal
            .RotateAround( Vector3.Zero, Rotation.FromYaw( Scene.Camera.Rotation.Yaw() ) );

        if ( Controller.IsOnGround )
        {
            _velocity = _velocity.WithZ( 0 );
            _velocity += wishDir * MoveSpeed;

            if ( Input.Pressed( "Jump" ) )
                _velocity = _velocity.WithZ( JumpForce );
        }
        else
        {
            _velocity += Vector3.Down * Gravity * Time.Delta;
        }

        Controller.Velocity = _velocity;
        Controller.Move();

        // Controller may modify velocity on collision
        _velocity = Controller.Velocity;
    }
}

Ground and Surface Checks

CSHARP
if ( Controller.IsOnGround )
{
    // safe to jump, play footstep, etc.
}

// What are we standing on?
if ( Controller.GroundObject.IsValid() )
{
    var surface = Controller.GroundObject.Components.Get<ModelRenderer>()?.Model?.SurfaceType;
}

Velocity Manipulation

CSHARP
// Knockback
Controller.Velocity += knockbackDirection * 400f;

// Teleport without physics
Controller.Velocity = Vector3.Zero;
WorldPosition = teleportTarget;

CharacterController vs Rigidbody

  • CharacterController — direct velocity control, step/slope handling, no mass. Use for players and NPCs.
  • Rigidbody — force-based, mass simulation, realistic collisions. Use for props and projectiles.
Was this helpful?