SleakEngine 1.0.0
C++23 multi-backend game engine
Loading...
Searching...
No Matches
FirstPersonController.hpp
Go to the documentation of this file.
1#ifndef _FIRSTPERSONCONTROLLER_HPP_
2#define _FIRSTPERSONCONTROLLER_HPP_
3
5#include <Core/OSDef.hpp>
7#include <string>
8
9namespace Sleak {
10
12
13 /// Grounded first-person character controller with mouse look, jumping,
14 /// sprinting, and an optional flight mode.
15 ///
16 /// Attach it to a Camera to get a player you can walk around with.
17 /// Movement follows Unreal's CharacterMovementComponent model:
18 /// acceleration toward a target speed, braking deceleration and ground
19 /// friction when input stops, and deliberately low air control so a
20 /// jump commits to its arc. `W`, `A`, `S`, `D` translate, the mouse
21 /// looks, and pitch is clamped to plus or minus 89 degrees.
22 ///
23 /// It needs a sibling RigidbodyComponent, which Initialize() looks up:
24 /// the rigidbody owns vertical motion and gravity, the controller owns
25 /// horizontal velocity. Add a ColliderComponent too, or the character
26 /// falls through the world.
27 ///
28 /// SetEnabled(false) releases the mouse and stops all input handling,
29 /// which is what you want when a menu or console opens. Re-enabling
30 /// resets velocity and re-syncs yaw and pitch to the camera's current
31 /// facing, so the view does not snap. SetFlying(true) switches to
32 /// noclip-style free flight, driven by SetVerticalFlyInput() for
33 /// up and down.
34 ///
35 /// @code{.cpp}
36 /// auto* cam = new Sleak::Camera("PlayerCamera",
37 /// Sleak::Math::Vector3D(8, 70, 8),
38 /// 60.0f, 0.1f, 1500.0f);
39 /// cam->AddComponent<Sleak::FirstPersonController>();
40 /// cam->AddComponent<Sleak::ColliderComponent>(
41 /// Sleak::Physics::BoundingSphere(
42 /// Sleak::Math::Vector3D(0, 0, 0), 0.3f));
43 /// cam->AddComponent<Sleak::RigidbodyComponent>(
44 /// Sleak::BodyType::Dynamic);
45 ///
46 /// if (auto* rb = cam->GetComponent<Sleak::RigidbodyComponent>()) {
47 /// rb->SetUseGravity(true);
48 /// rb->SetGravity(Sleak::Math::Vector3D(0.0f, -32.0f, 0.0f));
49 /// }
50 ///
51 /// if (auto* fpc = cam->GetComponent<Sleak::FirstPersonController>()) {
52 /// fpc->SetMaxWalkSpeed(4.5f);
53 /// fpc->SetSprintSpeedMultiplier(1.8f);
54 /// fpc->SetJumpZVelocity(6.0f);
55 /// fpc->SetSensitivity(0.1f);
56 /// }
57 ///
58 /// AddObject(cam);
59 /// cam->Initialize();
60 /// SetActiveCamera(cam);
61 /// @endcode
62 ///
63 /// @see CameraController, FreeLookCameraController, Camera,
64 /// RigidbodyComponent, ColliderComponent
65 /// @ingroup scene
66 class ENGINE_API FirstPersonController : public CameraController {
67 public:
69 ~FirstPersonController() override;
70
71 /// Grabs the sibling RigidbodyComponent and derives initial yaw/pitch from the camera's facing.
72 bool Initialize() override;
73 void Update(float deltaTime) override;
74 /// Toggles relative mouse mode and, when re-enabling, resets velocity and re-syncs yaw/pitch.
75 void SetEnabled(bool enabled) override;
76
77 void ToggleCursor(bool enable) override;
78
79 void SetMaxWalkSpeed(float speed) { m_maxWalkSpeed = speed; }
80 float GetMaxWalkSpeed() const { return m_maxWalkSpeed; }
81 void SetSprintSpeedMultiplier(float mult) { m_sprintMultiplier = mult; }
82 float GetSprintSpeedMultiplier() const { return m_sprintMultiplier; }
83 void SetJumpZVelocity(float vel) { m_jumpZVelocity = vel; }
84 float GetJumpZVelocity() const { return m_jumpZVelocity; }
85 void SetMaxAcceleration(float accel) { m_maxAcceleration = accel; }
86 void SetBrakingDeceleration(float decel) { m_brakingDeceleration = decel; }
87 void SetGroundFriction(float friction) { m_groundFriction = friction; }
88 void SetAirControl(float airControl) { m_airControl = airControl; }
89
90 // Fly
91 /// Switches between grounded movement and free-flight, resetting vertical velocity.
92 void SetFlying(bool flying);
93 bool IsFlying() const { return m_flying; }
94 void SetMaxFlySpeed(float speed) { m_maxFlySpeed = speed; }
95 float GetMaxFlySpeed() const { return m_maxFlySpeed; }
96 void SetFlySprintMultiplier(float mult) { m_flySprintMultiplier = mult; }
97 void SetVerticalFlyInput(float v) { m_flyVerticalInput = v; }
98
99 float GetPitch() const { return m_pitch; }
100 float GetYaw() const { return m_yaw; }
101 void SetPitch(float pitch) { m_pitch = pitch; }
102 void SetYaw(float yaw) { m_yaw = yaw; }
103
104 /// Updates translation/sprint input state from a key-down event.
105 void OnKeyPressed(const Events::Input::KeyPressedEvent& e);
106 /// Clears translation/sprint input state from a key-up event.
107 void OnKeyReleased(const Events::Input::KeyReleasedEvent& e);
108
109 private:
110 /// Reads mouse delta into yaw/pitch, clamped to m_pitchRange.
111 void UpdateInput(float deltaTime) override;
112 /// Applies UE-style acceleration/braking to velocity, resolves jump/fly, and moves the camera.
113 void UpdateCamera(float deltaTime) override;
114
115 // UE-style movement parameters — tuned slower for a calmer pace
116 float m_maxWalkSpeed = 2.5f; // Casual walking pace
117 float m_sprintMultiplier = 2.0f; // Sprint speed = walk * multiplier
118 bool m_sprinting = false;
119 float m_maxAcceleration = 10.0f; // Gentle ramp-up (~0.25s to full speed)
120 float m_brakingDeceleration = 12.0f; // Smooth stop
121 float m_groundFriction = 8.0f; // UE default
122 float m_airControl = 0.05f; // Minimal air control
123
124 // Jump — gentle hop, ~0.45m height
125 // v = sqrt(2 * 9.81 * 0.45) ≈ 2.97
126 float m_jumpZVelocity = 3.0f;
127
128 // Fly state
129 bool m_flying = false;
130 float m_maxFlySpeed = 10.0f;
131 float m_flySprintMultiplier = 2.5f;
132 float m_flyVerticalInput = 0.0f;
133 float m_flyVerticalVelocity = 0.0f;
134
135 // Mouse look
136 float m_pitch = 0.0f;
137 float m_yaw = 0.0f;
138 Math::Vector2D m_pitchRange = Math::Vector2D(-89, 89);
139
140 // Horizontal velocity (managed by controller, separate from rigidbody Y axis)
141 Math::Vector3D m_velocity;
142
143 // Input state
144 bool m_firstFrame = true;
145
146 RigidbodyComponent* m_rigidbody = nullptr;
147
148 std::string m_keyPressedHandlerId;
149 std::string m_keyReleasedHandlerId;
150 };
151
152} // namespace Sleak
153
154#endif // _FIRSTPERSONCONTROLLER_HPP_
CameraController(GameObject *object)
void Update(float deltaTime) override
bool Initialize() override
Grabs the sibling RigidbodyComponent and derives initial yaw/pitch from the camera's facing.
void SetEnabled(bool enabled) override
Toggles relative mouse mode and, when re-enabling, resets velocity and re-syncs yaw/pitch.
void ToggleCursor(bool enable) override
Shows or hides the OS cursor and, typically, toggles relative mouse mode.
Root namespace for everything the engine exposes.
Definition Camera.hpp:10