feat(engine): C++ native script system (ScriptBehavior + registry)

ScriptComponent stores only a script name string (POD, serializable);
instances are reconciled by ScriptRuntime each frame (PhysicsWorld
pattern): orphan/rename cleanup with OnDestroy, per-name instantiation
from a file-level self-registering registry (ENGINE_REGISTER_SCRIPT),
OnCreate on bind, OnUpdate after physics step on scaled dt. Engine
framerate loop only sees the base interface, so future Lua/C# behaviors
plug in as foreign ScriptBehavior implementations with zero engine
changes. Ships a Spinner sample script and Inspector script picker.
This commit is contained in:
2026-10-03 18:02:49 +08:00
parent ea6beee593
commit 3403822a52
10 changed files with 348 additions and 2 deletions
+38
View File
@@ -0,0 +1,38 @@
//
// Spinner.cpp:C++ 原生脚本示范——Y 轴匀速自转。
//
// 写脚本三步:
// 1. 新建 .cpp 放本目录(CMake 自动进构建)
// 2. 继承 ScriptBehavior,覆写 Name/OnCreate/OnUpdate/OnDestroy
// 3. 文件级 ENGINE_REGISTER_SCRIPT(类名) 自注册——Inspector 下拉
// 与场景序列化按该名解析
//
#include <Engine/Scripting/Script.h>
#include <glm/gtc/quaternion.hpp>
namespace {
class Spinner final : public Engine::Scripting::ScriptBehavior {
public:
const char* Name() const override { return "Spinner"; }
void OnCreate() override {
// 实体与组件已就位;需要别的组件时用 Get<T>()(不存在会炸)
}
void OnUpdate(float dt) override {
// 四元数复合绕 Y(避免每帧欧拉↔四元数往返累积失真)
const glm::quat step = glm::angleAxis(
glm::radians(m_Speed * dt), glm::vec3(0.0f, 1.0f, 0.0f));
Transform().SetRotationQuat(step * Transform().GetRotationQuat());
}
private:
float m_Speed = 90.0f; // 度/秒
};
ENGINE_REGISTER_SCRIPT(Spinner)
} // namespace