【虚幻C++笔记】枚举UENUM、结构体USTRUCT

虚幻C++枚举UENUM与结构体USTRUCT笔记

枚举(UENUM)

第一种:使用命名空间

UENUM(BlueprintType)
namespace MyEnumType
{
    enum MyCustomEnum
    {
       Type1,// 或者使用带 DisplayName别名 ==> Enum1 UMETA(DisplayName = "Type1"),
       Type2,
       Type3,
    }
}
//在蓝图中声明
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyEnumType")
TEnumAsByte<MyEnumType::MyCustomType> MyEnumType;

第二种:继承uint8通过申明class类别名来替代

UENUM(BlueprintType)
enum class MyEnumType2 : uint8
{
  Enum1 UMETA(DisplayName = "Type1"),
  Enum2 UMETA(DisplayName = "Type2"),
  Enum3 UMETA(DisplayName = "Type3"),
  Enum4 UMETA(DisplayName = "Type4"),
};

//在蓝图中声明
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyEnumType2")
TEnumAsByte<MyEnumType2> MyEnumType2;

结构体(USTRUCT)

// 暴露给蓝图
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MyStructType")
int32 Age;
// 不暴露给蓝图
int32 Age;
// 蓝图图表无法访问此UObject指针,但是指针对UE的反射、智能指针和垃圾回收系统可见。
UPROPERTY()
UObject* ObjectPointer;
//注意,定义结构体名称前要加F前缀,不然编译不通过。
USTRUCT(BlueprintType)
struct FMyCustomStruct
{
  GENERATED_USTRUCT_BODY()

  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  FString ID;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  FString Name;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  int32 Age;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  float Height;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  bool IsMan;
};

//结构体创建数据表格,需继承FTableRowBase
USTRUCT(BlueprintType)
struct FMyCustomStruct:public FTableRowBase
{
  GENERATED_USTRUCT_BODY()

  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  FString ID;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  FString Name;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  int32 Age;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  float Height;
  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyStructType")
  bool IsMan;
};
//在蓝图中声明
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "MyExposeOnSpawn", meta = (ExposeOnSpawn = "ExposeOnSpawnValue"))
FMyCustomStruct MyCustomStruct;

<think>我们正在使用虚幻引擎(Unreal Engine,简称UE)结合C++编写结构体。根据引用[2]中的示例,我们可以了解到在UE中创建结构体的基本方法。 在UE中,结构体通常用于组织相关数据,并且可以通过特定的宏来让结构体被蓝图(Blueprint)访问。以下是一个基本的步骤和示例: ### 步骤 1. **创建结构体**:在C++代码中定义结构体,使用`USTRUCT()`宏来标记该结构体,使其可以被UE识别和管理。 2. **添加宏**:在结构体内部,使用`GENERATED_BODY()`宏,这是UE反射系统所必需的。 3. **添加成员变量**:在结构体中添加成员变量,并使用`UPROPERTY()`宏来标记它们,以便可以在编辑器中编辑或蓝图访问。 4. **命名规范**:UE中的结构体命名通常以`F`开头(例如`FMyStruct`)。 ### 示例代码 根据引用[2],我们可以编写如下结构体: ```cpp // MyStruct.h #pragma once #include "CoreMinimal.h" #include "MyStruct.generated.h" // 必须包含,且文件名一般为"结构体名.generated.h" USTRUCT(BlueprintType) // 使结构体可在蓝图中使用 struct FMyStruct { GENERATED_BODY() // 必须添加,用于支持UE反射 public: // 添加一个可编辑且在蓝图中可读写的成员变量 UPROPERTY(EditAnywhere, BlueprintReadWrite) uint8 TestValue; // 示例成员,可以根据需要替换类型和变量名 // 可以添加多个成员变量 UPROPERTY(EditAnywhere, BlueprintReadWrite) FString Name; }; ``` ### 说明 - `USTRUCT(BlueprintType)`:这个宏表示该结构体可以在蓝图中作为变量类型使用。 - `GENERATED_BODY()`:这个宏必须放在结构体内部的最前面(在public访问修饰符之后),它生成了UE反射所需的代码。 - `UPROPERTY(EditAnywhere, BlueprintReadWrite)`:这个宏标记成员变量,使其可以在编辑器中的任意位置(如在放置在场景中的Actor的细节面板)编辑,并且在蓝图中可读可写。 ### 注意事项 1. **头文件**:结构体的声明通常放在头文件(.h)中。 2. **生成的头文件**:需要包含一个生成的头文件,其命名格式为`"YourStructName.generated.h"`,并且必须放在头文件的最后一行(除了注释)。注意,上面的示例中我们包含了`"MyStruct.generated.h"`(假设我们的结构体类名为`MyStruct`,但实际结构体名为`FMyStruct`,通常文件名和结构体名去掉F一致,但这里我们文件名用`MyStruct.h`,生成的头文件用`"MyStruct.generated.h"`)。 3. **访问修饰符**:结构体内部可以使用`public`、`private`等访问修饰符。为了让蓝图能够访问,成员变量通常需要放在`public`下。 ### 使用结构体 定义好了结构体后,我们可以在C++代码中像普通结构体一样使用它,也可以在蓝图中创建该结构体的变量。 例如,在C++中: ```cpp FMyStruct MyData; MyData.TestValue = 10; MyData.Name = TEXT("Hello"); ``` 在蓝图中,我们可以创建一个变量,类型选择为我们定义的结构体(例如`MyStruct`,注意在蓝图中显示的是去掉F的名字,即`MyStruct`)。 ### 相关问题 1. 如何在蓝图中使用自定义的结构体变量? 2. 在UE中,结构体与类有什么区别?什么情况下应该使用结构体而不是类? 3. 如何让结构体支持复制(Replication)? 4. 如何在UE编辑器中编辑结构体的默认值? [^1]: 引用[1]提到了C++在UE中的优势,如内存管理、面向对象和泛型编程,这些特性在编写结构体时同样适用。 [^2]: 引用[2]提供了创建结构体的具体代码示例。 [^3]: 引用[3]说明了C++模板和泛型编程,但在本例中我们不需要模板,因为UE的结构体使用宏来处理反射。 [^4]: 引用[4]是关于资源加载的,与结构体创建无关。 </think>### 虚幻引擎中编写C++结构体(Struct)的方法 在虚幻引擎(Unreal Engine)中创建结构体需遵循特定规范,确保与引擎反射系统兼容。以下是详细步骤和示例: --- #### **核心步骤** 1. **创建头文件** 新建`.h`文件(如 `MyStruct.h`),包含以下要素: ```cpp #pragma once #include "CoreMinimal.h" #include "MyStruct.generated.h" // 必需!自动生成反射代码 ``` 2. **定义结构体** 使用 `USTRUCT()` 宏和命名规范: ```cpp USTRUCT(BlueprintType) // BlueprintType允许蓝图访问 struct FMyStruct // 必须以"F"开头 { GENERATED_BODY() // 必需!启用反射系统 public: // 可编辑变量(支持蓝图读写) UPROPERTY(EditAnywhere, BlueprintReadWrite) int32 Health; UPROPERTY(EditAnywhere, BlueprintReadWrite) FString PlayerName; }; ``` 3. **使用结构体** 在C++类或蓝图中直接调用: ```cpp // C++ 示例 FMyStruct PlayerStats; PlayerStats.Health = 100; PlayerStats.PlayerName = "Alice"; ``` --- #### **关键规范说明** | 要素 | 作用 | |---------------------|----------------------------------------------------------------------| | `USTRUCT(BlueprintType)` | 允许结构体在蓝图中作为变量类型使用 | | `GENERATED_BODY()` | 生成虚幻引擎所需的反射代码,必须放在结构体内部开头 | | `UPROPERTY()` | 暴露变量到编辑器/蓝图(常用参数:`EditAnywhere`, `BlueprintReadWrite`) | | **命名规则** | 结构体名必须以 `F` 开头(如 `FVector`) | > 注意:结构体成员**不支持虚函数**和**继承**,需要复杂逻辑时应使用`UClass`[^2][^1] --- #### **显式特例化(高级场景)** 当泛型模板无法处理特殊类型时(如仅交换结构体的部分字段),需显式特例化: ```cpp // 泛型交换函数 template <typename T> void Swap(T& a, T& b) { ... } // 特例化:仅交换FMyStruct的PlayerName template <> void Swap<FMyStruct>(FMyStruct& a, FMyStruct& b) { FString temp = a.PlayerName; a.PlayerName = b.PlayerName; b.PlayerName = temp; } ``` 此方法适用于定制化数据处理[^3] --- #### **资源集成示例** 若结构体需关联资源(如静态网格),使用 `TSoftObjectPtr` 异步加载: ```cpp USTRUCT() struct FInventoryItem { GENERATED_BODY() UPROPERTY(EditAnywhere) TSoftObjectPtr<UStaticMesh> ItemMesh; // 软引用资源 }; ``` 通过 `StreamableManager` 实现安全加载[^4] --- ### 相关问题 1. 如何在蓝图中修改C++定义的结构体属性? 2. 结构体虚幻引擎的 `UCLASS` 有何本质区别? 3. 如何让结构体支持网络同步复制(Replication)? 4. 在性能敏感场景下,使用结构体有哪些优化技巧? [^1]: C++允许精细内存控制并支持面向对象范式,适用于资源有限的游戏平台 [^2]: 结构体需以`F`开头并通过`USTRUCT`/`GENERATED_BODY`启用反射 [^3]: 显式特例化可处理泛型模板无法操作的特定类型逻辑 [^4]: 异步加载资源需依赖虚幻引擎的`TSoftObjectPtr`和`FStreamableManager`
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值