Character movement
For a game where you have a character that can walk, run, jump, etc, you will need some generic character movement functionality. If you want to have complete control, you could implement this yourself, but there is also a built in character movement component that you can attach to your character actor.
Example
The actor implementation below illustrates how you can attach the CharacterMovementComponent
to an actor and pass in various properties to configure its behaviours. In the example we are also attaching a mesh component to give the character a visual representation. Also, the third person camera component is attached to have a camera following the character.
@Actor()
class CharacterActor extends BaseActor {
private physicsSystem = inject(PhysicsSystem)
private viewController = inject(ViewController)
private mesh = attach(MeshComponent, {
object: new Mesh(
new CylinderBufferGeometry(.5, .5, 2),
new MeshStandardMaterial({color: 0xffffff})
)
})
private thirdPersonCamera = attach(ThirdPersonCameraComponent)
public movement = attach(CharacterMovementComponent, {
autoStepMaxHeight: 0,
colliderHeight: 2,
colliderRadius: .5,
maxWalkingSlopeAngle: 70,
maxSpeed: 3,
maxSpeedBackwards: 3,
maxSpeedSprint: 7,
})
}
You likely want to tweak the parameters of the character movement component a lot to find something that works well for your game.
In this example, we make the movement component instance public because it provides an interface to control movement which we want to be accessible from a player controller.
Controlling the movement
With the above code, the character will simply fall to the ground where it is spawned and not move. To control the character you need to bind various action inputs that are exposed on the movement component.
directionInput - For controlling the movement of the character forward, backward, left and right
jumpInput - Toggle when you want the character to jump
sprintInput - Toggle to change the movement speed to the configured sprinting speed
rotationInput - Rotate the character around the y-axis to turn left and right.
The code example below illustrates how code could look inside a player controller using an injected InputService
and a referenced character actor with a movement component.
const playerMove = this.character.movement.directionInput
const playerJump = this.character.movement.jumpInput
const playerSprint = this.character.movement.sprintInput
this.inputService.bindToggle(InputAction.jump, playerJump.toggle)
this.inputService.bindToggle(InputAction.sprint, playerSprint.toggle)
this.inputService.bindToggle(InputAction.moveForward, playerMove.togglePositiveY)
this.inputService.bindToggle(InputAction.moveBackward, playerMove.toggleNegativeY)
this.inputService.bindToggle(InputAction.moveLeft, playerMove.toggleNegativeX)
this.inputService.bindToggle(InputAction.moveRight, playerMove.togglePositiveX)
this.inputService.bindDelta(
InputAction.rotate,
this.character.movement.rotationInput.rotateY
)
Read more about how to handle player input in the Player input guide.
Rotate to movement direction
The default settings for the character movement and the third person camera is that the camera is behind the character at all times and the character is also facing in the forward direction. This is appropriate for some games when you want the character to always face the direction the camera is looking such as third person shooters. In some other games, it is more fitting to be able to quickly change movement direction while running at full speed as opposed to strafing or walking backwards.
This can be accomplished by setting the option rotateToMovementDirection
to true in the movement component.
In this case, you often also want the camera to be able to rotate more freely so that the direction you run toward doesn't have to be the same direction that the camera is facing. To configure this, set fixedBehind
on the ThirdPersonCameraComponent
to false.
@Actor()
class CharacterActor extends BaseActor {
private thirdPersonCamera = attach(ThirdPersonCameraComponent, {
fixedBehind: false
})
public movement = attach(CharacterMovementComponent, {
rotateToMovementDirection: true
})
}
In the original input configuration, we only set up the character to be rotated when moving the mouse. However, in order to be able to spin the camera around more freely, we need to also update the third person camera component. See the code below for how bind a function that updates two rotation inputs simultaneously.
this.inputService.bindDelta(
InputAction.rotate,
(delta) => {
this.character.movement.rotationInput.rotateY(delta)
this.character.thirdPersonCamera.rotationInput.rotateY(delta)
}
)
It is also possible to change these parameters while the game is running. For example, you might rotate to movement direction for normal movement but when the character aims a ranged weapon, you may want to not rotate to movement direction, allowing you to strafe and walk backward while still facing in the same direction. Also, you set the camera to be fixed behind so that you can control where you are aiming.
See the code below for how you could toggle these parameters. You would likely also show a crosshair in the UI to help the player aim and update some state for character animation to play the a dedicated animation while aiming.
@Actor()
class CharacterActor extends BaseActor {
private thirdPersonCamera = attach(ThirdPersonCameraComponent, {
fixedBehind: false
})
public movement = attach(CharacterMovementComponent, {
rotateToMovementDirection: true
})
startAiming() {
this.thirdPersonCamera.fixedBehind = true
this.movement.rotateToMovementDirection = false
}
stopAiming() {
this.thirdPersonCamera.fixedBehind = false
this.movement.rotateToMovementDirection = true
}
}
Last updated