一、前言
结构体的定义和枚举类似,枚举的定义有两种方式。区别是结构体必须以“F”开头命名,而枚举不用。
额外再讲了一下蓝图生成时暴露变量的方法。
二、实现
2.1、结构体
1、定义结构体
代码如下,注意这个定义的代码一定要在“UCLASS()”的前面,否则会编译报错。另外结构体的命名也必须以“F”开头,否在也会编译报错。通过如下定义的结构体,在蓝图中可以创建一个新的变量,如图2.1.1所示,然后可以选中刚创建的类型变量。
USTRUCT(BlueprintType)
struct FMyStruct//必须以F开头
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStruct")
int32 Health;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStruct")
FString MyName;
};
UCLASS()

2、再定义结构体变量
通过如下代码定义一个上述结构体类型的变量,在蓝图中可以编辑和使用该类型的变量,如图2.1.2所示,为面板中的变量。图2.1.3为蓝图中调用该定义的变量。
//结构体
UPROPERTY(EditAnywhere,BlueprintReadWrite,Category="MyStruct")
FMyStruct MyStructValue;


3、结构体和数据表格进行绑定
在代码中创建一个新的结构体,该结构体继承数据表类,创建完后需要将所需的头文件添加到Including中,鼠标悬浮在”FTableRowBase"中通常会出现自动添加的提示按钮,编译。
USTRUCT(BlueprintType)
struct FDataStruct :public FTableRowBase
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyDataStruct")
int32 Age;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyDataStruct")
FString MyName;
};
然后在编辑器中创建数据表格,并选中刚刚创建的类型,如图2.1.4所示,打开数据表格即可看到

结构体的具体变量,在添加一个新的行数据后可以对变量进行赋值,如图2.1.5所示

还有一种创建CSV格式的文件,在文件中定义相同变量名的列数据,如图2.1.6所示为CSV格式的

表格数据,将其直接拖动到虚幻引擎中的内容处,会自动弹出数据表格的创建窗口,如图2.1.7所示,在行类型中选中刚刚创建的结构体,然后点击应用,这个就会将刚刚CSV表中的数据填充到此时创建的数据表中,如图2.1.8所示。


2.2、定义一个枚举
1、第一种方式
首先定义一个宏,代码如下,生成枚举的反射数据,通过反射将枚举暴露给蓝图,实现C++和蓝图的通信,BlueprintType的作用是可以在蓝图创建变量的时候也可以作为选项。其中UMETA是操作变量的属性更改,代码中修改最终展示的名字。
enum class MyCustomEnum1 :uint8
{
OneType UMETA(DisplayName = "One"),
TwoType UMETA(DisplayName = "Two"),
ThreeType UMETA(DisplayName = "Three"),
};
通过以下代码可以实现在各类面板和蓝图中使用该变量
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyEnum")
MyCustomEnum1 MyEnum1;
2、第二种方式
第二种定义枚举的方式代码如下,这种定义的MyEnumType里只能定义一个,超出会编译报错。
UENUM(BlueprintType)//生成枚举的反射数据,通过反射将枚举暴露给蓝图,实现C++和蓝图的通信,BlueprintType的作用是可以在蓝图创建变量的时候也可以作为选项
namespace MyEnumType
{
enum MyCustomEnum
{
Type1,
Type2,
Type3,
};
}
3、在蓝图中的呈现
如图2.2.1所示为第二种方式创建的变量在创建蓝图新变量时可以选中该枚举作为变量类型。

同时,在蓝图中也可以调用该枚举,如图2.2.2所示:

通过以下代码可以实现在各类面板和蓝图中使用该变量
//枚举
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyEnum")
TEnumAsByte<MyEnumType::MyCustomEnum> MyCustomEnum;
同时也可以在蓝图中调用和编辑该变量,如图2.2.3所示

2.3、蓝图生成时暴露
定义一个变量如下所示,在ExposeOnSpawn后面可以赋值也可以如下所示,不会影响后续的操作
/// <summary>
/// 生成蓝图时暴露的变量
/// </summary>
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyExposeOnSpawn", meta = (ExposeOnSpawn))
float myExposeOnSpawnValue;
然后在蓝图中可以在生成该类型的类的时候讲上述定义的变量暴露出来,如图2.3.1所示

这个和蓝图中定义的普通变量勾选”生产时公开“是一样的逻辑和道理。
三、总结
3.1、所有的定义都应该放在“UCLASS()”后面,否则会编译报错“Found 'USTRUCT' when expecting class while parsing class”。
3.2、结构体的命名必须以“F”开头,否则会编译报错“Struct 'MyStruct' has an invalid Unreal prefix, expecting 'FMyStruct”,枚举的命名不用任何固定开头。
3.3、两种枚举定义的方式不同,在C++代码中声明定义后的变量方式也不同。
3.4、结构体和数据表的关系。