Add concrete component script field support

This commit is contained in:
2026-04-03 16:51:42 +08:00
parent 73415915e6
commit e0e5c1fcaa
11 changed files with 507 additions and 4 deletions

View File

@@ -111,6 +111,7 @@ private:
struct FieldMetadata {
ScriptFieldType type = ScriptFieldType::None;
MonoClassField* field = nullptr;
MonoClass* componentClass = nullptr;
bool isEnum = false;
int32_t enumUnderlyingType = 0;
};
@@ -154,6 +155,8 @@ private:
bool DiscoverScriptClasses();
void DiscoverScriptClassesInImage(const std::string& assemblyName, MonoImage* image);
bool IsMonoBehaviourSubclass(MonoClass* monoClass) const;
bool IsSupportedComponentFieldClass(MonoClass* monoClass) const;
bool IsScriptComponentFieldClass(MonoClass* monoClass) const;
FieldMetadata BuildFieldMetadata(MonoClassField* field) const;
@@ -174,6 +177,7 @@ private:
bool ApplyStoredFields(const ScriptRuntimeContext& context, const ClassMetadata& metadata, MonoObject* instance);
MonoObject* CreateManagedGameObject(uint64_t gameObjectUUID);
bool HasSerializeFieldAttribute(MonoClassField* field) const;
bool TryExtractComponentReference(MonoObject* managedObject, ComponentReference& outReference) const;
bool TryExtractGameObjectReference(MonoObject* managedObject, GameObjectReference& outReference) const;
bool TrySetFieldValue(MonoObject* instance, const FieldMetadata& fieldMetadata, const ScriptFieldValue& value);
bool TryReadFieldValue(MonoObject* instance, const FieldMetadata& fieldMetadata, ScriptFieldValue& outValue) const;

View File

@@ -23,7 +23,8 @@ enum class ScriptFieldType {
Vector2,
Vector3,
Vector4,
GameObject
GameObject,
Component
};
struct GameObjectReference {
@@ -38,6 +39,20 @@ struct GameObjectReference {
}
};
struct ComponentReference {
uint64_t gameObjectUUID = 0;
uint64_t scriptComponentUUID = 0;
bool operator==(const ComponentReference& other) const {
return gameObjectUUID == other.gameObjectUUID
&& scriptComponentUUID == other.scriptComponentUUID;
}
bool operator!=(const ComponentReference& other) const {
return !(*this == other);
}
};
struct ScriptFieldMetadata {
std::string name;
ScriptFieldType type = ScriptFieldType::None;
@@ -99,7 +114,8 @@ using ScriptFieldValue = std::variant<
Math::Vector2,
Math::Vector3,
Math::Vector4,
GameObjectReference>;
GameObjectReference,
ComponentReference>;
struct ScriptFieldDefaultValue {
std::string fieldName;

View File

@@ -70,6 +70,11 @@ struct ScriptFieldTypeResolver<GameObjectReference> {
static constexpr ScriptFieldType value = ScriptFieldType::GameObject;
};
template<>
struct ScriptFieldTypeResolver<ComponentReference> {
static constexpr ScriptFieldType value = ScriptFieldType::Component;
};
class ScriptFieldStorage {
public:
template<typename T>