ScriptBehavior gains App() host access (Application injected via ScriptRuntime), TryGet<T> and EntityBits for physics facade addressing. WASDMove maps WASD to the editor camera's horizontal heading (UE gameplay convention): dynamic bodies go through the physics velocity facade preserving the vertical component (zeroing Y would cancel gravity mid-fall), bodiless entities translate their transform directly. Editor-mode key conflict is naturally avoided: RMB-held flight consumes WASD, release hands keys to the script.
72 lines
2.8 KiB
C++
72 lines
2.8 KiB
C++
//
|
||
// WASDMove.cpp:WASD 控制实体移动(相机水平朝向参考,UE gameplay 语义)。
|
||
//
|
||
// 移动语义分派:
|
||
// - Dynamic 刚体 → 走物理速度门面(每帧喂水平速度,Y 归物理——
|
||
// 重力/跳跃不受影响;松键喂零速 = 立即停,Unity velocity 语义)
|
||
// - 无刚体 → 直接平移 Transform
|
||
//
|
||
// 编辑器形态键位天然不冲突:RMB 按住 = 相机吃 WASD 飞行(脚本也读
|
||
// 到按键 → 同时在动,测移动时松开 RMB 即可);游戏形态 WASD 常开。
|
||
//
|
||
|
||
#include <Engine/Scripting/Script.h>
|
||
#include <Engine/Core/Application.h>
|
||
#include <Engine/Core/Window.h>
|
||
#include <Engine/Renderer/Renderer.h>
|
||
#include <Engine/Renderer/EditorCamera.h>
|
||
#include <Engine/Physics/PhysicsWorld.h>
|
||
|
||
#include <GLFW/glfw3.h>
|
||
#include <glm/glm.hpp>
|
||
#include <glm/gtc/quaternion.hpp>
|
||
|
||
namespace {
|
||
|
||
class WASDMove final : public Engine::Scripting::ScriptBehavior {
|
||
public:
|
||
const char* Name() const override { return "WASDMove"; }
|
||
|
||
void OnUpdate(float dt) override {
|
||
// 位移方向 = 视线水平投影(W 前进 / A 左 / D 右),UE Scene
|
||
// view 移动惯例;Y 锁 0(升降/跳跃归物理或将来扩展)
|
||
const glm::quat cq = App().GetRenderer()
|
||
.GetEditorCamera()
|
||
.GetTransform()
|
||
.GetRotationQuat();
|
||
const glm::vec3 fwd = cq * glm::vec3(0.0f, 0.0f, -1.0f);
|
||
const glm::vec3 right = cq * glm::vec3(1.0f, 0.0f, 0.0f);
|
||
|
||
auto& win = App().GetWindow();
|
||
glm::vec3 move(0.0f);
|
||
if (win.IsKeyPressed(GLFW_KEY_W)) move += fwd;
|
||
if (win.IsKeyPressed(GLFW_KEY_S)) move -= fwd;
|
||
if (win.IsKeyPressed(GLFW_KEY_D)) move += right;
|
||
if (win.IsKeyPressed(GLFW_KEY_A)) move -= right;
|
||
move.y = 0.0f;
|
||
if (glm::length(move) > 1e-4f) {
|
||
move = glm::normalize(move);
|
||
}
|
||
const glm::vec3 vel = move * m_Speed;
|
||
|
||
if (auto* rb = TryGet<Engine::ECS::RigidBodyComponent>();
|
||
rb != nullptr && rb->bodyValid &&
|
||
rb->type == Engine::ECS::RigidBodyComponent::BodyType::Dynamic) {
|
||
// 物理驱动:只覆写水平速度,Y 保留物理积分离散结果
|
||
//(整体喂 0 会抵消重力 → 空中物体悬浮)
|
||
auto& phy = App().GetPhysics();
|
||
const glm::vec3 cur = phy.GetLinearVelocity(EntityBits());
|
||
phy.SetLinearVelocity(EntityBits(), {vel.x, cur.y, vel.z});
|
||
} else {
|
||
Transform().SetPosition(Transform().GetPosition() + vel * dt);
|
||
}
|
||
}
|
||
|
||
private:
|
||
float m_Speed = 5.0f; // m/s
|
||
};
|
||
|
||
ENGINE_REGISTER_SCRIPT(WASDMove)
|
||
|
||
} // namespace
|