This repository contains a small set of Unity scripts that provide a basic first-person player. The code is modular so you can use only the parts you need. Everything is easy to change through the Inspector.
Who this is for
- Beginners learning how player controllers work.
- Developers who want a simple, tweakable starting point for first-person controls.
What is included
PlayerInput- simple input wrapper that exposesMove,Look,RunHeld, andConsumeJump().PlayerMovement- walking, running, jumping, coyote time, and smooth acceleration.PlayerStamina- simple sprint stamina with drain and recharge.MouseLook- camera rotation with optional tilt and smoothing.HeadBob- camera bobbing, breathing, and FOV effects with collision handling.Compat/- small shims so code compiles without internal project packages.
Minimum requirements
- Unity 2019.4 or newer. Unity 2020.3 LTS is recommended.
Setup
- Copy the
Playerfolder into your project'sAssetsfolder. - Open the project in Unity and wait for scripts to compile.
- Create an empty GameObject called
Playerat the scene origin. - Add a
CharacterControllercomponent toPlayer(built-in component). - Add these scripts to the
PlayerGameObject:PlayerInput,PlayerMovement, and optionallyPlayerStamina. - Create a child GameObject for the camera. Add your
Cameraunder it. - Attach
MouseLookto the camera or its parent, and attachHeadBobto the camera.
Starter inspector values
PlayerMovement: WalkSpeed = 2, RunSpeed = 4, JumpHeight = 1.2MouseLook: MouseSensitivity = 0.2, LookSmoothTime = 0.06HeadBob: UseHeadBob = true, BobFrequency = 12
Basic controls (default)
- Move: W/A/S/D or arrow keys
- Look: Mouse
- Run: Left Shift
- Jump: Space
How to use in your game
- Read runtime state from
PlayerMovement(e.g.,IsGrounded,CurrentVelocity) to drive animations. - Bind UI to
PlayerStamina.OnStaminaStateChangedor readStaminaPercenteach frame. - Use
PlayerMovement.PauseMovement()to freeze player input during dialog or menus. CallResumeMovement()when done.
Technical details
- Components are small, single-responsibility MonoBehaviours. Public properties provide runtime state; methods are side-effect free except where intended (for example
SetSprinting). PlayerInputbuilds simple Input System actions at runtime. If you prefer another input layer, keep the public properties (Move,Look,RunHeld,ConsumeJump()) and replace the internal bindings.PlayerMovementrelies onCharacterControllerfor collision and grounding. Movement usesMathf.MoveTowardsfor speed smoothing and separate gravity integration for stable jumping and coyote time.PlayerStaminaupdates viaCompat/UpdateManagerwhen the project's event system is not present. It exposesOnStaminaStateChangedand also publishesStaminaChangedEventtoGameEventBusif available.HeadBobandMouseLookuse SmoothDamp and time-scaled timers so motion is frame-rate independent. Camera collision is handled with a sphere cast to avoid clipping into geometry.Compat/contains small shims:UpdateManager(per-frame callbacks),GameEventBus(Publish no-op),StaminaChangedEvent, andProfilerMarkers. Replace these with your game's systems for tighter integration.- Performance notes: avoid heavy work in Update callbacks. The included
UpdateManagerbatches callbacks; if you integrate into an existing scheduler prefer grouped updates and early returns when components are disabled. - Extensibility: read/write the public properties from other scripts, subscribe to
OnStaminaStateChanged, or override a component by subclassing and swapping the script on the GameObject.
Where to go next
- See docs/USAGE.md for detailed setup and troubleshooting.
- See docs/API.md for quick code snippets and examples.
License
- MIT. See LICENSE for details.