feat(app): WASDMove script (WASD camera-relative movement)

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.
This commit is contained in:
2026-10-03 18:27:12 +08:00
parent 3403822a52
commit cad0481bc0
5 changed files with 106 additions and 5 deletions
+19 -1
View File
@@ -27,6 +27,9 @@
#include <vector>
namespace Engine {
class Application; // 宿主门面(Window/Renderer/Physics 入口),实现见 ScriptRuntime.cpp
namespace Scripting {
class ScriptBehavior {
@@ -52,17 +55,32 @@ namespace Engine {
return m_Scene->GetRegistry().get<T>(m_Entity);
}
template<typename T>
T* TryGet() {
return m_Scene->GetRegistry().try_get<T>(m_Entity);
}
// 绑定实体的 entityBits(物理门面按键值寻址)
u32 EntityBits() const {
return static_cast<u32>(entt::to_integral(m_Entity));
}
// 宿主应用(GetWindow/GetRenderer/GetPhysics/GetScene……)
Application& App() const;
bool Valid() const { return m_Scene != nullptr && m_Entity != entt::null; }
private:
friend class ScriptRuntime;
void Bind(ECS::Scene& scene, entt::entity e) {
void Bind(ECS::Scene& scene, entt::entity e, Application* app) {
m_Scene = &scene;
m_Entity = e;
m_App = app;
}
ECS::Scene* m_Scene = nullptr;
entt::entity m_Entity = entt::null;
Application* m_App = nullptr;
};
// ---- 按名注册表:脚本类文件级自注册,运行时按名实例化 ----
@@ -14,6 +14,9 @@
#include <unordered_map>
namespace Engine {
class Application;
namespace Scripting {
// 实例簿记:行为对象 + OnCreate 是否已调
@@ -24,7 +27,8 @@ namespace Engine {
class ScriptRuntime {
public:
explicit ScriptRuntime(ECS::Scene& scene) : m_Scene(scene) {}
explicit ScriptRuntime(ECS::Scene& scene, Application* app = nullptr)
: m_Scene(scene), m_App(app) {}
// 每帧调用(吃 scaled dt):对账 → OnCreate(新实例)→ OnUpdate
void Update(f32 dt);
@@ -33,6 +37,7 @@ namespace Engine {
void Sync();
ECS::Scene& m_Scene;
Application* m_App; // 注入脚本上下文
std::unordered_map<u32, ScriptInstance> m_Instances; // entityBits
};