feat: add interactable component and test button

This commit is contained in:
2026-10-16 23:25:11 +02:00
parent faba4171ec
commit 7dd5ee7903
14 changed files with 236 additions and 6 deletions
@@ -1,4 +1,5 @@
#include <components/FirstPersonController.h>
#include <components/Interactable.h>
#include <glm/glm.hpp>
#include <glm/gtx/norm.hpp>
@@ -69,6 +70,8 @@ void FirstPersonController::Update(float dt)
SetMouseCaptured(!IsMouseCaptured());
}
m_FocusedInteractable = nullptr;
if (!IsMouseCaptured())
{
m_JumpHeld = false;
@@ -85,7 +88,6 @@ void FirstPersonController::Update(float dt)
return;
}
// Jump presses are remembered for a moment, so pressing just before landing still jumps
m_JumpBufferTimer = std::max(m_JumpBufferTimer - dt, 0.0f);
if (input.WasKeyPressed(SDL_SCANCODE_SPACE))
{
@@ -96,6 +98,35 @@ void FirstPersonController::Update(float dt)
m_Yaw += static_cast<float>(input.MouseDeltaX()) * m_MouseSensitivity;
m_Pitch -= static_cast<float>(input.MouseDeltaY()) * m_MouseSensitivity;
m_Pitch = glm::clamp(m_Pitch, glm::radians(-89.0f), glm::radians(89.0f));
m_FocusedInteractable = FindFocusedInteractable();
if (m_FocusedInteractable != nullptr && input.WasKeyPressed(SDL_SCANCODE_E))
{
m_FocusedInteractable->Interact(*GetGameObject());
}
}
glm::vec3 FirstPersonController::GetLookDirection() const
{
return glm::vec3{
std::cos(m_Yaw) * std::cos(m_Pitch),
std::sin(m_Pitch),
std::sin(m_Yaw) * std::cos(m_Pitch),
};
}
Interactable* FirstPersonController::FindFocusedInteractable() const
{
if (m_Rigidbody == nullptr || m_Rigidbody->GetPhysicsWorld() == nullptr)
return nullptr;
PhysicsRaycastHit hit{};
if (!m_Rigidbody->GetPhysicsWorld()->Raycast(
GetEyePosition(), GetLookDirection(), m_InteractDistance, hit, m_Rigidbody->GetBody()))
{
return nullptr;
}
return Interactable::FindOnObjectOrParents(hit.object);
}
void FirstPersonController::FixedUpdate(float fixedDt)
@@ -220,6 +251,7 @@ void FirstPersonController::ImGuiInspector()
ImGui::DragFloat("Fall Gravity Multiplier", &m_FallGravityMultiplier, 0.01f, 1.0f, 5.0f);
ImGui::DragFloat("Coyote Time", &m_CoyoteTime, 0.005f, 0.0f, 1.0f);
ImGui::DragFloat("Jump Buffer Time", &m_JumpBufferTime, 0.005f, 0.0f, 1.0f);
ImGui::DragFloat("Interact Distance", &m_InteractDistance, 0.05f, 0.0f, 20.0f);
ImGui::DragFloat("Mouse Sensitivity", &m_MouseSensitivity, 0.0001f, 0.0f, 0.1f);
ImGui::DragFloat("Eye Height", &m_EyeHeight, 0.01f, -2.0f, 2.0f);
ImGui::Text("Grounded: %s", m_Grounded ? "yes" : "no");
@@ -244,6 +276,7 @@ nlohmann::json FirstPersonController::Serialize() const
{"fallGravityMultiplier", m_FallGravityMultiplier},
{"coyoteTime", m_CoyoteTime},
{"jumpBufferTime", m_JumpBufferTime},
{"interactDistance", m_InteractDistance},
{"mouseSensitivity", m_MouseSensitivity},
{"eyeHeight", m_EyeHeight},
{"yaw", m_Yaw},
@@ -262,6 +295,7 @@ void FirstPersonController::Deserialize(const nlohmann::json& data)
m_FallGravityMultiplier = data.value("fallGravityMultiplier", m_FallGravityMultiplier);
m_CoyoteTime = data.value("coyoteTime", m_CoyoteTime);
m_JumpBufferTime = data.value("jumpBufferTime", m_JumpBufferTime);
m_InteractDistance = data.value("interactDistance", m_InteractDistance);
m_MouseSensitivity = data.value("mouseSensitivity", m_MouseSensitivity);
m_EyeHeight = data.value("eyeHeight", m_EyeHeight);
m_Yaw = data.value("yaw", m_Yaw);