feat(physics): dispatch PhysX simulation events to scene scripts

This commit is contained in:
2026-04-15 13:36:39 +08:00
parent 077786e4c7
commit 51aea47c83
20 changed files with 955 additions and 7 deletions

View File

@@ -28,6 +28,15 @@ enum class ScriptLifecycleMethod {
OnDestroy
};
enum class ScriptPhysicsMessage {
CollisionEnter = 0,
CollisionStay,
CollisionExit,
TriggerEnter,
TriggerStay,
TriggerExit
};
struct ScriptClassDescriptor {
std::string assemblyName;
std::string namespaceName;
@@ -96,6 +105,10 @@ public:
const ScriptRuntimeContext& context,
ScriptLifecycleMethod method,
float deltaTime) = 0;
virtual void InvokePhysicsMessage(
const ScriptRuntimeContext& context,
ScriptPhysicsMessage message,
Components::GameObject* other) = 0;
};
} // namespace Scripting

View File

@@ -104,9 +104,19 @@ public:
bool CreateScriptInstance(const ScriptRuntimeContext& context) override;
void DestroyScriptInstance(const ScriptRuntimeContext& context) override;
void InvokeMethod(const ScriptRuntimeContext& context, ScriptLifecycleMethod method, float deltaTime) override;
void InvokePhysicsMessage(
const ScriptRuntimeContext& context,
ScriptPhysicsMessage message,
Components::GameObject* other) override;
private:
static constexpr size_t LifecycleMethodCount = 8;
static constexpr size_t PhysicsMessageCount = 6;
struct PhysicsMessageMethods {
MonoMethod* withGameObject = nullptr;
MonoMethod* withoutArgs = nullptr;
};
struct FieldMetadata {
ScriptFieldType type = ScriptFieldType::None;
@@ -123,6 +133,7 @@ private:
std::string fullName;
MonoClass* monoClass = nullptr;
std::array<MonoMethod*, LifecycleMethodCount> lifecycleMethods{};
std::array<PhysicsMessageMethods, PhysicsMessageCount> physicsMessageMethods{};
std::unordered_map<std::string, FieldMetadata> fields;
};
@@ -161,6 +172,7 @@ private:
FieldMetadata BuildFieldMetadata(MonoClassField* field) const;
static const char* ToLifecycleMethodName(ScriptLifecycleMethod method);
static const char* ToPhysicsMessageMethodName(ScriptPhysicsMessage message);
const ClassMetadata* FindClassMetadata(
const std::string& assemblyName,
@@ -184,7 +196,7 @@ private:
void ClearManagedInstances();
void ClearClassCache();
bool InvokeManagedMethod(MonoObject* instance, MonoMethod* method);
bool InvokeManagedMethod(MonoObject* instance, MonoMethod* method, void** args = nullptr);
void RecordException(MonoObject* exception);
void SetError(const std::string& error);

View File

@@ -38,6 +38,10 @@ public:
const ScriptRuntimeContext& context,
ScriptLifecycleMethod method,
float deltaTime) override;
void InvokePhysicsMessage(
const ScriptRuntimeContext& context,
ScriptPhysicsMessage message,
Components::GameObject* other) override;
};
} // namespace Scripting

View File

@@ -33,6 +33,10 @@ public:
void OnFixedUpdate(float fixedDeltaTime);
void OnUpdate(float deltaTime);
void OnLateUpdate(float deltaTime);
void DispatchPhysicsMessage(
Components::GameObject* gameObject,
ScriptPhysicsMessage message,
Components::GameObject* other);
void OnScriptComponentEnabled(ScriptComponent* component);
void OnScriptComponentDisabled(ScriptComponent* component);
@@ -140,6 +144,10 @@ private:
bool ShouldScriptRun(const ScriptInstanceState& state) const;
bool EnsureScriptReady(ScriptInstanceState& state, bool invokeEnableIfNeeded);
void InvokeLifecycleMethod(ScriptInstanceState& state, ScriptLifecycleMethod method, float deltaTime = 0.0f);
void InvokePhysicsMessage(
ScriptInstanceState& state,
ScriptPhysicsMessage message,
Components::GameObject* other);
void StopTrackingScript(ScriptInstanceState& state, bool runtimeStopping);
NullScriptRuntime m_nullRuntime;