Added animations for swimming
This commit is contained in:
@@ -27,6 +27,7 @@
|
||||
#include "components/RigidBody.hpp"
|
||||
#include "components/GeneratedPhysicsTag.hpp"
|
||||
#include "components/BuoyancyInfo.hpp"
|
||||
#include "components/InWater.hpp"
|
||||
#include "components/WaterPhysics.hpp"
|
||||
#include "components/WaterPlane.hpp"
|
||||
#include "components/Light.hpp"
|
||||
@@ -493,6 +494,7 @@ void EditorApp::setupECS()
|
||||
// Register game components
|
||||
m_world.component<StartupMenuComponent>();
|
||||
m_world.component<PlayerControllerComponent>();
|
||||
m_world.component<InWater>();
|
||||
|
||||
// Register CellGrid/Town components
|
||||
CellGridModule::registerComponents(m_world);
|
||||
|
||||
12
src/features/editScene/components/InWater.hpp
Normal file
12
src/features/editScene/components/InWater.hpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef EDITSCENE_INWATER_HPP
|
||||
#define EDITSCENE_INWATER_HPP
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* Tag component indicating the entity is currently in water.
|
||||
* Automatically added/removed by BuoyancySystem.
|
||||
*/
|
||||
struct InWater {
|
||||
};
|
||||
|
||||
#endif // EDITSCENE_INWATER_HPP
|
||||
@@ -21,6 +21,11 @@ struct PlayerControllerComponent {
|
||||
Ogre::String idleState = "idle";
|
||||
Ogre::String walkState = "walking";
|
||||
Ogre::String runState = "running";
|
||||
|
||||
/* Swim animation states (used when character is in water) */
|
||||
Ogre::String swimIdleState = "swim-idle";
|
||||
Ogre::String swimState = "swim";
|
||||
Ogre::String swimFastState = "swim-fast";
|
||||
};
|
||||
|
||||
#endif // EDITSCENE_PLAYERCONTROLLER_HPP
|
||||
|
||||
@@ -52,6 +52,15 @@ void BuoyancySystem::update(float deltaTime)
|
||||
// Clear previous frame's water bodies
|
||||
m_bodiesInWater.clear();
|
||||
|
||||
// Remove InWater tag from entities that were in water last frame
|
||||
for (flecs::entity_t id : m_entitiesInWater) {
|
||||
flecs::entity e = m_world.entity(id);
|
||||
if (e.is_alive() && e.has<InWater>()) {
|
||||
e.remove<InWater>();
|
||||
}
|
||||
}
|
||||
m_entitiesInWater.clear();
|
||||
|
||||
// Perform broadphase query to find bodies in water
|
||||
// Use water surface position from WaterPhysics component, camera XZ position
|
||||
Ogre::Vector3 waterSurfacePos(m_cameraPosition.x,
|
||||
@@ -101,6 +110,12 @@ void BuoyancySystem::update(float deltaTime)
|
||||
continue;
|
||||
}
|
||||
|
||||
// Mark entity as in water
|
||||
if (!entity.has<InWater>()) {
|
||||
entity.add<InWater>();
|
||||
}
|
||||
m_entitiesInWater.insert(entity.id());
|
||||
|
||||
// Debug logging for buoyancy application
|
||||
if (m_debugEnabled) {
|
||||
Ogre::Vector3 bodyPos = m_physics->getPosition(bodyID);
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <unordered_map>
|
||||
#include "../physics/physics.h"
|
||||
#include "../components/BuoyancyInfo.hpp"
|
||||
#include "../components/InWater.hpp"
|
||||
#include "../components/WaterPhysics.hpp"
|
||||
#include "../components/Transform.hpp"
|
||||
|
||||
@@ -91,6 +92,9 @@ private:
|
||||
// Cache for scene node -> entity mapping
|
||||
std::unordered_map<Ogre::SceneNode *, flecs::entity_t> m_nodeToEntity;
|
||||
|
||||
// Entities that were in water last frame (for InWater tag management)
|
||||
std::set<flecs::entity_t> m_entitiesInWater;
|
||||
|
||||
// Query for entities with BuoyancyInfo component
|
||||
flecs::query<BuoyancyInfo> m_buoyancyInfoQuery;
|
||||
};
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "PlayerControllerSystem.hpp"
|
||||
#include "../EditorApp.hpp"
|
||||
#include "../components/PlayerController.hpp"
|
||||
#include "../components/InWater.hpp"
|
||||
#include "../components/Character.hpp"
|
||||
#include "../components/Transform.hpp"
|
||||
#include "../components/EntityName.hpp"
|
||||
@@ -362,13 +363,24 @@ void PlayerControllerSystem::updateLocomotion(PlayerControllerComponent &pc,
|
||||
if (!ats)
|
||||
return;
|
||||
|
||||
bool inWater = state.targetEntity.has<InWater>();
|
||||
Ogre::String animState;
|
||||
if (!isMoving) {
|
||||
animState = pc.idleState;
|
||||
} else if (input.shift) {
|
||||
animState = pc.runState;
|
||||
if (inWater) {
|
||||
if (!isMoving) {
|
||||
animState = pc.swimIdleState;
|
||||
} else if (input.shift) {
|
||||
animState = pc.swimFastState;
|
||||
} else {
|
||||
animState = pc.swimState;
|
||||
}
|
||||
} else {
|
||||
animState = pc.walkState;
|
||||
if (!isMoving) {
|
||||
animState = pc.idleState;
|
||||
} else if (input.shift) {
|
||||
animState = pc.runState;
|
||||
} else {
|
||||
animState = pc.walkState;
|
||||
}
|
||||
}
|
||||
|
||||
if (!animState.empty()) {
|
||||
|
||||
@@ -2189,6 +2189,9 @@ nlohmann::json SceneSerializer::serializePlayerController(flecs::entity entity)
|
||||
json["idleState"] = pc.idleState;
|
||||
json["walkState"] = pc.walkState;
|
||||
json["runState"] = pc.runState;
|
||||
json["swimIdleState"] = pc.swimIdleState;
|
||||
json["swimState"] = pc.swimState;
|
||||
json["swimFastState"] = pc.swimFastState;
|
||||
return json;
|
||||
}
|
||||
|
||||
@@ -2222,6 +2225,9 @@ void SceneSerializer::deserializePlayerController(flecs::entity entity,
|
||||
pc.idleState = json.value("idleState", pc.idleState);
|
||||
pc.walkState = json.value("walkState", pc.walkState);
|
||||
pc.runState = json.value("runState", pc.runState);
|
||||
pc.swimIdleState = json.value("swimIdleState", pc.swimIdleState);
|
||||
pc.swimState = json.value("swimState", pc.swimState);
|
||||
pc.swimFastState = json.value("swimFastState", pc.swimFastState);
|
||||
entity.set<PlayerControllerComponent>(pc);
|
||||
}
|
||||
|
||||
|
||||
@@ -78,6 +78,35 @@ bool PlayerControllerEditor::renderComponent(flecs::entity entity,
|
||||
modified = true;
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
ImGui::Text("Swim States (used when in water)");
|
||||
|
||||
char swimIdleBuf[256];
|
||||
snprintf(swimIdleBuf, sizeof(swimIdleBuf), "%s",
|
||||
pc.swimIdleState.c_str());
|
||||
if (ImGui::InputText("Swim Idle State", swimIdleBuf,
|
||||
sizeof(swimIdleBuf))) {
|
||||
pc.swimIdleState = swimIdleBuf;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
char swimBuf[256];
|
||||
snprintf(swimBuf, sizeof(swimBuf), "%s",
|
||||
pc.swimState.c_str());
|
||||
if (ImGui::InputText("Swim State", swimBuf, sizeof(swimBuf))) {
|
||||
pc.swimState = swimBuf;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
char swimFastBuf[256];
|
||||
snprintf(swimFastBuf, sizeof(swimFastBuf), "%s",
|
||||
pc.swimFastState.c_str());
|
||||
if (ImGui::InputText("Swim Fast State", swimFastBuf,
|
||||
sizeof(swimFastBuf))) {
|
||||
pc.swimFastState = swimFastBuf;
|
||||
modified = true;
|
||||
}
|
||||
|
||||
ImGui::Unindent();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user