C++的類別可以分為POD(Plain Old Data)以及非POD。POD可以對應到UnrealScript的struct;而非POD的類別則要對應到UnrealScript的class,也就是必須繼承UObject才行。這種類別稱為固有類別(Intrinsic Class)。
固有類別比起一般的C++類別多了一些要注意的事項:
- 必須直接或間接繼承UObject
- 要在類別定義內使用DECLARE_CLASS_INTRINSIC巨集
- 若有想要在UnrealScript中使用的欄位,要在成員函式StaticConstructor註冊。
- 若有參考到UnrealScript物件的欄位,必需使用EmitObjectReference函式或AddReferencedObjects函式註冊。
- 可在成員函式InitializeIntrinsicPropertyValues給定欄位初值。
- 在AUTO_INITIALIZE_REGISTRANTS_XXX使用StaticClass()註冊,XXX替換成實際的Script Package名稱。
固有類別註冊過的欄位,不僅在UnrealScript中可以使用,也可以在PropertyWindow中存取。
範例
以下程式碼示範如何定義固有類別:
class FMyPOD { public: UBOOL MyBool; FName MyName; };上面的C++ POD類別如果要在UnrealScript中當作struct使用,就需要產生對應的UScriptStruct才行:
UScriptStruct* MakeMyPODStruct(UStruct* Outer, TCHAR* Name) { UScriptStruct* Struct = new(Outer,Name,RF_Public|RF_Transient|RF_Native) UScriptStruct(NULL); INT StructPropertyOffset = 0; new(Struct,TEXT("MyBool"),RF_Public) UBoolProperty(EC_CppProperty,StructPropertyOffset,TEXT(""), CPF_Edit | CPF_Native); StructPropertyOffset += sizeof(UBOOL); new(Struct,TEXT("MyName"),RF_Public) UNameProperty(EC_CppProperty,StructPropertyOffset,TEXT(""), CPF_Edit | CPF_Native); StructPropertyOffset += sizeof(FName); return Struct; }然而UScriptStruct需要放在一個UnrealScript類別內,所以在此就撰寫一個固有類別來存放它,順便也示範如何定義一個固有類別:
class UMyIntrinsicClass : public UObject { DECLARE_CLASS_INTRINSIC(UMyIntrinsicClass,UObject,CLASS_CollapseCategories|0,UDKGame); public: INT MyInt; FLOAT MyFloat; FString MyString; FMyPOD MyPOD; void StaticConstructor(); void InitializeIntrinsicPropertyValues(); };主要是在StaticConstructor()裡針對想要在UnrealScript中使用的欄位產生對應的UProperty,如果並不想被UnrealScript處理的話是不需要特別註冊。
IMPLEMENT_CLASS(UMyIntrinsicClass); void UMyIntrinsicClass::StaticConstructor() { UProperty* MyIntProp = new(GetClass(),TEXT("MyInt"), RF_Public) UIntProperty( CPP_PROPERTY(MyInt), TEXT(""), CPF_Edit ); UProperty* MyFloatProp = new(GetClass(),TEXT("MyFloat"), RF_Public) UFloatProperty( CPP_PROPERTY(MyFloat), TEXT(""), CPF_Edit ); UProperty* MyStringProp = new(GetClass(),TEXT("MyString"), RF_Public) UFloatProperty( CPP_PROPERTY(MyString), TEXT(""), CPF_Edit ); UScriptStruct* MyStruct = MakeMyPODStruct(GetClass(), TEXT("MyPOD")); MyStruct->SetPropertiesSize(sizeof(FMyPOD)); MyStruct->AllocateStructDefaults(); FArchive ArDummy0; MyStruct->Link(ArDummy0,0); UProperty* MyStuctProp = new(GetClass(),TEXT("MyStuct"),RF_Public) UStructProperty(CPP_PROPERTY(MyPOD),TEXT(""),CPF_Edit,MyStruct); }
沒有留言:
張貼留言