The prefab at Assets/prefabs/PlatformerController.prefab is set up as a proper player prefab:
Playerroot GameObjectCharacterControllerPlatformerPlayerController
Bodychild GameObjectSkinnedModelRendererusingmodels/citizen/citizen.vmdlCitizenAnimationHelpertargeting the skinned model renderer
The startup scene (Assets/scenes/minimal.scene) includes a Player instance at 0,0,80. The scene camera is assigned directly to the player's PlatformerPlayerController.CameraTarget, so movement, camera follow, respawn, and animation are handled by one component.
Movement uses Input.AnalogMove.x first, so keyboard movement and gamepad left-stick movement work with s&box defaults. Named-action fallback fields are now exposed on the controller:
LeftActiondefaults toLeftRightActiondefaults toRightJumpActiondefaults toJumpRunActiondefaults toRunDuckActiondefaults toDuck
If one of those names does not exist in Project Settings/Input, either add the input action or change the string on PlatformerPlayerController.
The controller drives the Citizen model's built-in animation graph through CitizenAnimationHelper.
It feeds these values every frame:
- actual controller velocity via
WithVelocity - requested/wish movement via
WithWishVelocity - grounded state via
IsGrounded - walk/run state via
MoveStyle - facing/look direction via
WithLook - jump starts via
TriggerJump - optional duck/crouch blend via
DuckLevel
This means the Citizen skinned model uses its own idle, walk, run, jump, fall, landing, and crouch-style graph behavior instead of the controller forcing raw sequence names.
Important prefab references:
PlatformerPlayerController.BodyRenderershould point to theBodyskinned model renderer.PlatformerPlayerController.AnimationHelpershould point to theBodycitizen animation helper.CitizenAnimationHelper.Targetshould point to theBodyskinned model renderer.SkinnedModelRenderer.UseAnimGraphshould stay enabled.
- Walk and run movement.
- Ground/air acceleration and ground friction.
- Faster turn-around acceleration for responsive direction changes.
- Input dead zone for stick drift.
- Configurable input action names.
- Coyote time and jump buffering.
- Variable jump height.
- Apex-hang gravity for less floaty but more readable jumps.
- Faster falling, capped max fall speed, and ground-stick velocity.
- Optional extra air jumps.
- 2.5D Y-axis lock.
- Facing direction on the visual child only, so the root/controller stays clean.
- Citizen animation helper integration including jump and duck values.
- Built-in side-view camera follow with a player focus offset, look-ahead, smoothed look-ahead, small dead zone, snap-on-start, and automatic look-at rotation so the player stays framed.
- Fall respawn using a configurable
KillZ,RespawnPoint, andSafeGroundRespawnHeight.
The controller now treats the camera as a side-view platformer camera:
CameraOffsetdefaults to0,-620,140, which keeps the camera behind the 2.5D plane instead of offsetting heavily on X.CameraFocusOffsetdefaults to0,0,48, so the camera looks at the Citizen body/chest area instead of the player's feet.CameraLooksAtPlayerkeeps the camera rotated toward that focus point every frame.CameraLookAheadis intentionally modest so the player remains visible while moving.
If the player is too high/low in frame, tune CameraFocusOffset.z first. If the camera is too close/far, tune CameraOffset.y.
Most values are exposed as [Property] fields on PlatformerPlayerController:
WalkSpeed/RunSpeedGroundAcceleration/AirAccelerationTurnAroundMultiplierGroundFrictionInputDeadZoneJumpSpeedGravityFallGravityMultiplierLowJumpGravityMultiplierApexHangGravityMultiplierApexHangVelocityMaxFallSpeedGroundStickVelocityCoyoteTimeJumpBufferTimeExtraAirJumpsCameraTargetCameraOffsetCameraFocusOffsetCameraLooksAtPlayerCameraFollowSharpnessCameraLookAheadCameraLookAheadSharpnessCameraVerticalLookAheadCameraDeadZoneX/CameraDeadZoneZBodyRendererAnimationHelperUseCitizenAnimationTriggerCitizenJumpAnimationAnimationSpeedDeadZoneAnimationDuckLerpSpeedRespawnWhenFallingKillZRespawnPointSafeGroundRespawnHeight
PlatformerPlayerController exposes IsGrounded, Velocity, MoveInput, Facing, IsRunActive, IsJumpHeld, IsDuckHeld, and CanBufferedJump, which makes it easier to add sound effects, dust particles, attack states, health, checkpoints, or state logic without rewriting the movement core.
The controller locks the player to the Y depth axis for a 2.5D platformer. Disable LockDepthAxis if you want free 3D movement.
The controller now launches jumps through CharacterController.Punch( Vector3.Up * JumpSpeed ) by default.
This is intentional: directly setting CharacterController.Velocity.z while the controller still thinks it is grounded can trigger the Citizen jump animation without physically separating the controller from the floor. Punch is the safer s&box CharacterController path for jump impulses.
New jump-related tuning fields:
UseCharacterControllerPunchForJump- keep this enabled for normal jumping.JumpUngroundNudge- tiny upward nudge after jumping to avoid same-tick ground snapping.PostJumpGroundGraceTime- brief grace window where animation/logic treats the player as airborne immediately after a jump.