返回 导航

UE5

hangge.com

UE5 - UC++中的UStruct使用详解(定义/创建/持有/UStruct、获取结构体信息)

作者:hangge | 2026-10-28 10:31

一、结构体在原生 C++和 Unreal Engine C++ 中的区别

1,C++中的结构体

(1)在原生 C++ 中,结构体(Structure)是一种很常见的数据结构。

(2)在原生 C++ 中,结构体(Strut)和类(Class)没有本质上的区别。要说唯一的区别, 就在于 Struct 默认所有成员变量和函数的权限都是 Public 的,而类的成员变量和函数默认权限是 Private 的。结构体和类都支持在栈或者堆上被创建,能够直接被持有,也可以通过指针来引用。 

2,UC++中的结构体

(1)在 UC++ 中,纳入 UC++ 体系的结构体叫作 UStruct。

(2)UStruct 和 UClass 是有区别的。
  • 对于 UStruct,UE5 更加希望它是类似于 C 语言时代的 POD 类型(Plain Old Data),也就是只有数据,没有操作。
  • 在 UStruct 中,只支持添加成员变量 UProperty,但是不能像 UClass 一样添加 UFunction。
  • 注意,虽然不能添加 UFunction,但是 UStruct 本质上还是 C++ 中的 Struct,所以它是可以添加普通的成员函数的。 

(3)总结起来,我们在一个 UStruct 中可以包括:
  • UPROPERTY 成员变量; 
  • 非 UPROPERTY 的成员变量(但是不会被纳入 UC++ 管理); 
  • 非 UFUNCTION 的成员函数(无法被 UE 捕获到函数的信息)。 

(4)同时,UE5 中的 UStruct 一定要有一个默认的不带参数的构造函数。这意味着我们可以不写任何构造函数,让编译器自动生成一个默认构造函数;也可以自己手写一个不带参的构造函数。 

二、UStruct 的使用

1,创建 UStruct

(1)与创建 UClass 不同的是,在 UE5 的编辑器中没有让我们以可视化形式创建新的 UStruct 的途径,所以我们需要手动创建。 首先我们要打开 VS,创建一个新的头文件。首先我们要打开 VS,创建一个新的头文件。在 Solution Explorer 中,找到 Source 文件夹,右击空白处,在弹出的菜单中选择“Add”→“New Item”来增加一个文件

(2)在弹出的面板中,选择“Header File(头文件)”,然后将文件命名为“MyDataStruct.h”。同时我们还需要选择头文件所在的路径。通过窗口底部的 Location 选项,选择项目所在目录下的“Source\项目名”目录,比如我这里就是“Source\demo3”

(3)创建 MyDataStruct.h 头文件后,写入如下代码。
UStruct 需要注意的问题和编写 UObject 类似:
  • 头文件的第一行 #pragma once 是为了避免头文件被重复 include。
  • 第三行是编写 UStruct 和 UObject 时的必要头文件 CoreMinimal.h,详细说明见我之前写的文章(点击查看)。
  • 第四行中,包含了 MyDataStruct.generated.h 头文件。这个与 MyDataStruct 头文件同名的文件是 UE5 帮我们自动生成的,但是需要我们手动 include。 MyDataStruct.generated.h 头文件中包含了一些要插入到结构体的额外信息。在编译之前如果写入这句代码,可能 VS 会提示文件不存在,不用管它,在一次编译之后这个文件就会被生成。
  • USTRUCT() 宏,用来标记结构体为 UStruct。与 UCLASS() 宏类似,也可以通过设置一些说明符来更改 UStruct 的特性,比如说添加 BlueprintType 说明符后, 就可以将这个结构体暴露到蓝图。
  • 结构体的名字应该以 F 开头。
  • 在结构体中,与 UObject 一样,需要在结构体的第一行添加 GENERATED_BODY() 宏。这个宏用来在结构体中插入一些必要的信息。
  • 结构体必须要有一个不带参数的构造函数。
#pragma once

#include "CoreMinimal.h"
#include "MyDataStruct.generated.h"
USTRUCT(BlueprintType)
struct FMyDataStruct
{
	GENERATED_BODY()

	//想要让蓝图识别到成员变量,一定要写成BlueprintReadWrite或BlueprintReadOnly 
	UPROPERTY(BlueprintReadWrite, EditAnywhere)
	int32 IntValue;

	//默认构造函数
	FMyDataStruct() : FMyDataStruct(0) {}
	FMyDataStruct(int32 InIntValue) : IntValue(InIntValue) {}
};

(4)编译项目后打开编辑器。由于我们在 USTRUCT 宏中添加了 BlueprintType 说明符, 所以这个结构体应该可以在蓝图中使用。 任意打开一个蓝图,在蓝图类编辑器的空白处右击,在节点搜索框中搜索“MyDataStruct”,就可以找到 Make MyDataStruct 节点,这个节点会创建出一个 FMyDataStruct 实例。

2,UStruct 实例的创建与持有

(1)与 UObject 不同的是,我们不会使用类似于创建 NewObject 的方式来创建一个实例并且获得指向实例的指针,而是直接使用构造函数创建一个 UStruct 实例。
FMyDataStruct MyDataStruct;
FMyDataStruct MyDataStruct2(1);

(2)当 UStruct 作为 UPROPERTY 时,与基础类型一样,使用的是非指针的形式。
UPROPERTY()
FMyDataStruct DataStruct;

3,获取结构体的信息

(1)之前讲 UObject 的时候提到过(点击查看),可以使用 类名::StaticClass() 来获取 UClass 指针类型的类信息,并尝试了打印类名。类似的,对于一个 UStruct,我们也可以使用 结构体名::StaticStruct() 来获取结构体信息。 

(2)例如下面代码可以打印结构体 FMyDataStruct 的名称。 
UStruct* StructInfo = FMyDataStruct::StaticStruct();
UE_LOG(LogTemp, Log, TEXT("Struct name: %s"), *(StructInfo->GetName()));
评论

全部评论(0)

回到顶部