|
| 1 | +--- |
| 2 | +order: 3 |
| 3 | +title: Character Controller |
| 4 | +type: Physics |
| 5 | +label: Physics |
| 6 | +--- |
| 7 | + |
| 8 | +Character Controller ([CharacterController](/apis/core/#CharacterController)) is a special type of collider component specifically designed for handling character movement. It provides specialized movement algorithms and collision detection, capable of handling steps, slopes, and other complex terrains, making it particularly suitable for first-person or third-person game character control. |
| 9 | + |
| 10 | +## Usage |
| 11 | + |
| 12 | +1. Select the target entity and click the Add Component button in the inspector to add the CharacterController component. |
| 13 | + |
| 14 | +<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*nEMXRKiqpy8AAAAAAAAAAAAAesJ_AQ/original" /> |
| 15 | + |
| 16 | +2. Set the collision shape of the controller to match the character's appearance as closely as possible. For detailed instructions on collision shapes, please refer to the [Collision Shape](/docs/physics/collider/colliderShape) documentation. |
| 17 | + |
| 18 | +<Callout type="positive"> |
| 19 | +Unlike other colliders, the character controller can only add one collision shape. It is generally recommended to use a capsule shape (CapsuleColliderShape) as the character's collision shape. |
| 20 | +</Callout> |
| 21 | + |
| 22 | +<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*4QvUTI4D89EAAAAAAAAAAAAAesJ_AQ/original" /> |
| 23 | + |
| 24 | +<Image src="https://mdn.alipayobjects.com/huamei_3zduhr/afts/img/A*aRGqSIMqDmsAAAAAAAAAAAAAesJ_AQ/original" /> |
| 25 | + |
| 26 | +3. Adjust the properties of the collider as needed to modify the physical behavior of the object. The meaning and function of each property are explained below. |
| 27 | + |
| 28 | +## Property Explanation |
| 29 | + |
| 30 | + |
| 31 | +### Inherited from Collider |
| 32 | +| Property | Description | |
| 33 | +| ----------------------------------------- | ----------------- | |
| 34 | +| [**shapes**](/apis/core/#Collider-shapes) | Collection of collision shapes | |
| 35 | + |
| 36 | +### CharacterController Specific Properties |
| 37 | +| Property | Description | Default Value | |
| 38 | +| ---- | ---- | ------ | |
| 39 | +| [**stepOffset**](/apis/core/#CharacterController-stepOffset) | The maximum step height the character can automatically step over. <ul><li>Must be greater than or equal to 0</li><li>Actual step height = stepOffset + contact offset of the collision shape</li></ul> | 0.5 | |
| 40 | +| [**slopeLimit**](/apis/core/#CharacterController-slopeLimit) | The maximum slope angle (degrees) the character can walk on. <ul><li>Slopes steeper than this angle will be treated as walls</li><li>Affects the character's ability to climb slopes</li></ul> | 45° | |
| 41 | +| [**nonWalkableMode**](/apis/core/#CharacterController-nonWalkableMode) | Defines how to handle non-walkable surfaces. <ul><li>PreventClimbing: Prevents the character from climbing non-walkable slopes but does not force other movements (default)</li><li>PreventClimbingAndForceSliding: Prevents the character from climbing non-walkable slopes and forces the character to slide down the slope</li></ul> | PreventClimbing | |
| 42 | +| [**upDirection**](/apis/core/#CharacterController-upDirection) | Defines the upward direction of the character. The default is (0, 1, 0), which is the Y-axis in world space. Affects the direction determination for movement and collision detection | (0, 1, 0) | |
| 43 | + |
| 44 | +## Methods |
| 45 | + |
| 46 | + |
| 47 | +### Inherited from Collider |
| 48 | +| Method Name | Description | |
| 49 | +| --------------------------------------------------- | ----------------- | |
| 50 | +| [**addShape**](/apis/core/#Collider-addShape) | Add a collision shape | |
| 51 | +| [**removeShape**](/apis/core/#Collider-removeShape) | Remove a specified collision shape | |
| 52 | +| [**clearShapes**](/apis/core/#Collider-clearShapes) | Clear all collision shapes | |
| 53 | + |
| 54 | +### CharacterController Specific Methods |
| 55 | +| Method Name | Description | |
| 56 | +| ---- | ---- | |
| 57 | +| [**move**](/apis/core/#CharacterController-move) | Moves the character controller. Returns a collision flag value indicating the collision state. <ul><li>displacement: Movement vector</li><li>minDist: Minimum movement distance</li><li>elapsedTime: Elapsed time</li></ul> | |
| 58 | + |
| 59 | +### Collision Flags |
| 60 | + |
| 61 | +The `move()` function returns a collision flag value that indicates the collision state of the character controller with the environment. These flags can be checked using bitwise AND operations (&): |
| 62 | + |
| 63 | +| Flag Name | Value | Description | |
| 64 | +|---------|----|----| |
| 65 | +| None | 0 | No collision occurred | |
| 66 | +| Sides | 1 | Collided with sides | |
| 67 | +| Up | 2 | Collided with the top (e.g., ceiling) | |
| 68 | +| Down | 4 | Collided with the bottom (e.g., ground) | |
| 69 | + |
| 70 | +## Script Usage |
| 71 | + |
| 72 | +### Basic Configuration |
| 73 | +```typescript |
| 74 | +// Create character controller |
| 75 | +const controller = entity.addComponent(CharacterController); |
| 76 | + |
| 77 | +// Add capsule shape |
| 78 | +const capsule = new CapsuleColliderShape(); |
| 79 | +capsule.radius = 0.5; |
| 80 | +capsule.height = 2; |
| 81 | +controller.addShape(capsule); |
| 82 | + |
| 83 | +// Configure controller properties |
| 84 | +controller.stepOffset = 0.5; // Set step height |
| 85 | +controller.slopeLimit = 45; // Set maximum walkable slope angle |
| 86 | +controller.upDirection = new Vector3(0, 1, 0); // Set upward direction |
| 87 | +``` |
| 88 | + |
| 89 | +### Using the Move Function |
| 90 | +```typescript |
| 91 | +class CharacterMovement extends Script { |
| 92 | + private _velocity = new Vector3(); |
| 93 | + |
| 94 | + onUpdate() { |
| 95 | + const controller = this.entity.getComponent(CharacterController); |
| 96 | + const deltaTime = engine.deltaTime; |
| 97 | + |
| 98 | + // Create displacement vector |
| 99 | + const displacement = new Vector3(); |
| 100 | + Vector3.scale(this._velocity, deltaTime, displacement); |
| 101 | + |
| 102 | + // Execute movement and get collision flags |
| 103 | + // minDist: Minimum movement distance, usually set to 0 |
| 104 | + // deltaTime: Elapsed time for physics calculations |
| 105 | + const collisionFlags = controller.move(displacement, 0, deltaTime); |
| 106 | + |
| 107 | + // Handle collision response |
| 108 | + if (collisionFlags & ControllerCollisionFlag.Down) { |
| 109 | + // Character is on the ground |
| 110 | + } |
| 111 | + } |
| 112 | +} |
| 113 | +``` |
| 114 | + |
| 115 | +### Collision Flags |
| 116 | + |
| 117 | +The `move()` function returns a collision flag value indicating the character controller's collision state with the environment. These flags can be checked using bitwise AND (&) operations: |
| 118 | + |
| 119 | +| Flag Name | Value | Description | |
| 120 | +|---------|----|----| |
| 121 | +| None | 0 | No collision occurred | |
| 122 | +| Sides | 1 | Collision with sides | |
| 123 | +| Up | 2 | Collision with ceiling | |
| 124 | +| Down | 4 | Collision with ground | |
| 125 | + |
| 126 | +Usage example: |
| 127 | +```typescript |
| 128 | +const flags = controller.move(displacement, 0, deltaTime); |
| 129 | + |
| 130 | +// Check if touching ground |
| 131 | +if (flags & ControllerCollisionFlag.Down) { |
| 132 | + // Character is on ground |
| 133 | + this._isGrounded = true; |
| 134 | +} |
| 135 | + |
| 136 | +// Check if hitting ceiling |
| 137 | +if (flags & ControllerCollisionFlag.Up) { |
| 138 | + // Character hit ceiling |
| 139 | + this._velocity.y = 0; |
| 140 | +} |
| 141 | + |
| 142 | +// Check if hitting walls |
| 143 | +if (flags & ControllerCollisionFlag.Sides) { |
| 144 | + // Character hit wall |
| 145 | + this._handleWallCollision(); |
| 146 | +} |
| 147 | + |
| 148 | +// Check multiple flags |
| 149 | +if ((flags & ControllerCollisionFlag.Down) && |
| 150 | + (flags & ControllerCollisionFlag.Sides)) { |
| 151 | + // Character is touching both ground and wall |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +### Walking on Slopes/Steps |
| 156 | + |
| 157 | +1. **Walking on Slopes** |
| 158 | +```typescript |
| 159 | +// Control the walkable slope angle by setting slopeLimit |
| 160 | +controller.slopeLimit = 60; // Allow steeper slopes |
| 161 | + |
| 162 | +// Set the handling method for non-walkable slopes |
| 163 | +controller.nonWalkableMode = ControllerNonWalkableMode.PreventClimbingAndForceSliding; // Slide down steep slopes |
| 164 | +``` |
| 165 | + |
| 166 | +2. **Adjusting Step Height** |
| 167 | +```typescript |
| 168 | +// Adjust stepOffset to control the maximum step height |
| 169 | +controller.stepOffset = 0.3; // Lower steps |
| 170 | +controller.stepOffset = 0.5; // Higher steps |
| 171 | +``` |
| 172 | + |
| 173 | +For a complete example, refer to: |
| 174 | +<Playground href="/embed/physx-controller" /> |
0 commit comments