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);
}
沒有留言:
張貼留言