Last active
July 3, 2018 22:29
-
-
Save trentpolack/223e24ea8f8302536b22ebfa94825fd4 to your computer and use it in GitHub Desktop.
A sample data structure and its corresponding UE4 object for easy JSON serialization/deserialization.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// FMechPartDataBase Data Structure. | |
// This structure is solely for serialization/deserialization purposes (it gets transferred to the UObject instance after that process is done). | |
USTRUCT( ) | |
struct FMechPartDataBase_SerializationStructure | |
{ | |
GENERATED_BODY( ) | |
public: | |
FMechPartDataBase_SerializationStructure( ) | |
: ConfigName( NAME_None ) | |
, PartType( 0 ) | |
, Mass( 1.0f ) | |
, HealthMax( 1.0f ) | |
, AssetPath_MaterialPrimary( NAME_None ) | |
, AssetPath_MaterialSecondary( NAME_None ) | |
, AssetPath_MaterialAccent( NAME_None ) | |
, AssetPath_MaterialChrome( NAME_None ) | |
, AssetPath_MaterialMisc( NAME_None ) | |
, AssetPath_SoundCue_Impact( NAME_None ) | |
, AssetPath_SoundCue_Ricochet( NAME_None ) | |
{ } | |
public: | |
/* | |
* Config Name. | |
*/ | |
UPROPERTY( ) | |
FName ConfigName; | |
/* | |
* Part Details. | |
*/ | |
UPROPERTY( ) | |
uint8 PartType; | |
UPROPERTY( ) | |
float Mass; | |
UPROPERTY( ) | |
float HealthMax; | |
/* | |
* Asset Reference Paths. | |
*/ | |
UPROPERTY( ) | |
FName AssetPath_MaterialPrimary; | |
UPROPERTY( ) | |
FName AssetPath_MaterialSecondary; | |
UPROPERTY( ) | |
FName AssetPath_MaterialAccent; | |
UPROPERTY( ) | |
FName AssetPath_MaterialChrome; | |
UPROPERTY( ) | |
FName AssetPath_MaterialMisc; | |
UPROPERTY( ) | |
FName AssetPath_SoundCue_Impact; | |
UPROPERTY( ) | |
FName AssetPath_SoundCue_Ricochet; | |
}; | |
// UMechPartDataBase Class Definition. | |
// This is the class used for actual game code (as opposed to the data structure below, which is strictly for serialization. | |
UCLASS( BlueprintType ) | |
class UMechPartDataBase : public UObject | |
{ | |
GENERATED_BODY( ) | |
public: | |
UMechPartDataBase( const class FObjectInitializer& ObjectInitializer ); | |
private: | |
UPROPERTY( ) | |
FMechPartDataBase_SerializationStructure BaseDataStructure; | |
protected: | |
// TSharedPtr< FMechPartDataBase_SerializationStructure > DataStructure; | |
FMechPartDataBase_SerializationStructure* DataStructure; | |
UPROPERTY( ) | |
TEnumAsByte< EMechPartType::Type > PartType; | |
public: | |
virtual void SetSerializationData( const FMechPartDataBase_SerializationStructure* SerializationData ); | |
// Read-only access to the data structure (weapon data structure, specifically, unlike the prior two). | |
const FMechPartDataBase_SerializationStructure& GetBaseSerializationDataRead( ) const; | |
// Writable access to the data structure (weapon data structure). | |
void GetBaseSerializationDataWrite( FMechPartDataBase_SerializationStructure& SerializationDataOut ); | |
FMechPartDataBase_SerializationStructure& GetBaseSerializationDataWrite( ); | |
public: | |
// NOTE (trent, 1/25/18): These accessor-generation macros do not result in the methods they define being treated as UFUNCTIONs (blueprint-exposable). | |
#define DEFINE_METHOD_SET_ACCESSOR( MemberType, Member ) \ | |
FORCEINLINE_DEBUGGABLE void Set##Member( MemberType Member ) \ | |
{ \ | |
DataStructure->##Member = Member; \ | |
} | |
#define DEFINE_METHOD_GET_ACCESSOR( MemberType, Member ) \ | |
FORCEINLINE_DEBUGGABLE MemberType Get##Member( ) const \ | |
{ \ | |
return DataStructure->##Member; \ | |
} | |
#define DEFINE_METHOD_ACCESSORS( MemberType, Member ) \ | |
DEFINE_METHOD_SET_ACCESSOR( MemberType, Member ) \ | |
DEFINE_METHOD_GET_ACCESSOR( MemberType, Member ) | |
// Mech part type. | |
inline void SetPartType( TEnumAsByte< EMechPartType::Type > PartTypeIn ) | |
{ | |
PartType = PartTypeIn; | |
DataStructure->PartType = PartTypeIn; | |
} | |
inline TEnumAsByte< EMechPartType::Type > GetPartType( ) const | |
{ | |
return PartType; | |
} | |
// Part JSON config name. | |
DEFINE_METHOD_ACCESSORS( const FName&, ConfigName ) | |
DEFINE_METHOD_ACCESSORS( float, Mass ) | |
DEFINE_METHOD_ACCESSORS( float, HealthMax ) | |
DEFINE_METHOD_ACCESSORS( const FName&, AssetPath_MaterialPrimary ) | |
DEFINE_METHOD_ACCESSORS( const FName&, AssetPath_MaterialSecondary ) | |
DEFINE_METHOD_ACCESSORS( const FName&, AssetPath_MaterialAccent ) | |
DEFINE_METHOD_ACCESSORS( const FName&, AssetPath_MaterialChrome ) | |
DEFINE_METHOD_ACCESSORS( const FName&, AssetPath_MaterialMisc ) | |
DEFINE_METHOD_ACCESSORS( const FName&, AssetPath_SoundCue_Impact ) | |
DEFINE_METHOD_ACCESSORS( const FName&, AssetPath_SoundCue_Ricochet ) | |
#undef DEFINE_METHOD_ACCESSORS | |
#undef DEFINE_METHOD_GET_ACCESSOR | |
#undef DEFINE_METHOD_SET_ACCESSOR | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Just carrying over my comments from the Gamasutra article:
Why use
FName
s instead ofFSoftObjectPath
/TSoftObjectPtr
? The latter would let you take advantage of the UI controls (i.e. picking asset with the content browser etc.) together with UI type safety.Your accessor macros will be ignored by
UnrealHeaderTool
(it only does simplified parsing), so all theUFUNCTION()
macros won't do anything (i.e. UHT will not generate reflection code for them).Finally, why bother making members private if you then declare a bunch of boilerplate accessors, granting (almost) full access to the members in question? Why not just make them public in the first place?