UE4学习笔记2——宏、类型等基础总结
2018-03-28 17:24
2206 查看
其实文档都有,做个整理方便查询:
类类型(UObject、AActor、UActorComponent 和 UStruct):
属性序列化
垃圾回收
按命名查找 UObject
可配置属性数值
属性和方法网络支持
AActor:拥有一系列事件,可在生命周期中进行调用:
BeginPlay - 对象首次出现在游戏进程中时调用
Tick - 每帧调用一次,在一段时间内执行操作
EndPlay - 对象离开游戏进程时调用
UActorComponent :通常为 AActor 指定的是与其在游戏中全局作用相关的高级目标,而 UActorComponent 通常执行的是支持这些高级目标的单个任务。组件也可附着到其他组件,或为 Actor 的根组件。组件只能附着到一个父组件或 Actor,但可被多个子组件附着。
RootComponent - 这是在 AActor 组件树中拥有顶层组件的 AActor 成员
Ticking - 组件作为拥有 AActor Tick() 的部分被点击
UStruct:使用 UStruct 时不必从任意特定类进行延展,只需要使用 USTRUCT() 标记结构体,编译工具将执行基础工作。和 UObject 不同,UStruct 不会被垃圾回收。如创建其动态实例,则必须自行管理其生命周期。UStruct 为纯旧式数据类型。它们拥有 UObject 反射支持,以便在虚幻编辑器、蓝图操作、序列化和网络通信中进行编辑。
反射系统:
UE4 使用其自身的反射实现,可启用动态功能,如垃圾回收、序列化、网络复制和蓝图/C++ 通信。这些功能为选择加入,意味着您需要为类型添加正确的标记,否则引擎将无视类型,不生成反射数据。
UCLASS() - 告知虚幻引擎生成类的反射数据。类必须派生自 UObject。常用说明符如下:
Blueprintable - 此类可由蓝图延展。
BlueprintReadOnly - 此属性只可从蓝图读取,不可写入。
Category - 定义此属性出现在编辑器 Details 视图下的部分。用于组织。
BlueprintCallable - 可从蓝图调用此函数。
USTRUCT()
4000
- 告知虚幻引擎生成结构体的反射数据。UFUNCTION 说明符列表GENERATED_BODY() - UE4 使用它替代为类型生成的所有必需样板文件代码。UPROPERTY() - 使 UCLASS 或 USTRUCT 的成员变量可用作 UPROPERTY。UPROPERTY 用途广泛。它允许变量被复制、被序列化,并可从蓝图中进行访问。垃圾回收器还使用它们来追踪对 UObject 的引用数。UPROPERTY 说明符列表UFUNCTION() - 使 UCLASS 或 USTRUCT 的类方法可用作 UFUNCTION。UFUNCTION 允许类方法从蓝图中被调用,并在其他资源中用作 RPC。UFUNCTION 说明符列表
UCLASS() 范例:#include "MyObject.generated.h"
UCLASS(Blueprintable)
class UMyObject : public UObject
{
GENERATED_BODY()
public:
MyUObject();
UPROPERTY(BlueprintReadOnly, EditAnywhere)
float ExampleProperty;
UFUNCTION(BlueprintCallable)
void ExampleFunction();
};首先注意 - “MyClass.generated.h”文件已包含。虚幻引擎将生成所有反射数据并将放入此文件。必须在声明类型的头文件中将此文件作为最后的 include 包含。同时可以在标记上添加额外的说明符,通过说明符可对类型拥有的特定行为进行说明。
派生自 对象 的类前缀为 U,如 UComponent。
枚举 的前缀为 E,如 EFortificationType。
接口 类的前缀通常为 I,如 IAbilitySystemInterface。
模板 类的前缀为 T,如 TArray。
派生自 SWidget(Slate UI)的类前缀为 S,如 SButton。
其余类的前缀均为 字母 F ,如 FVector。
int16/uint16 :16 位带符号/不带符号 整数
int32/uint32 :32 位带符号/不带符号 整数
int64/uint64 :64 位带符号/不带符号整数
标准 浮点 (32-bit) 和 双倍(64-bit)类型也支持浮点数。UE4有一个模板 TNumericLimits,用于找到数值类型支持的最小和最大范围。如需了解详情,请查阅此 链接 。
FText WidgetText = FText::Format(
LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"),
FText::FromString(TEXT("FtestPluginModule::OnSpawnPluginTab")),
FText::FromString(TEXT("testPlugin.cpp"))
);
完整要点:FText API
完整要点:角色编码部分函数会需要它。如 FString::Printf,‘%s’ 字符串格式说明符需要 TCHAR,而非 FString。
类类型(UObject、AActor、UActorComponent 和 UStruct):
UObject:(不常用)此类结合 UClass (包含UObject派生类实例的所有元数据)提供引擎中最重要的若干基础服务:
属性和方法反射属性序列化
垃圾回收
按命名查找 UObject
可配置属性数值
属性和方法网络支持
AActor:拥有一系列事件,可在生命周期中进行调用:
BeginPlay - 对象首次出现在游戏进程中时调用
Tick - 每帧调用一次,在一段时间内执行操作
EndPlay - 对象离开游戏进程时调用
UActorComponent :通常为 AActor 指定的是与其在游戏中全局作用相关的高级目标,而 UActorComponent 通常执行的是支持这些高级目标的单个任务。组件也可附着到其他组件,或为 Actor 的根组件。组件只能附着到一个父组件或 Actor,但可被多个子组件附着。
RootComponent - 这是在 AActor 组件树中拥有顶层组件的 AActor 成员
Ticking - 组件作为拥有 AActor Tick() 的部分被点击
UStruct:使用 UStruct 时不必从任意特定类进行延展,只需要使用 USTRUCT() 标记结构体,编译工具将执行基础工作。和 UObject 不同,UStruct 不会被垃圾回收。如创建其动态实例,则必须自行管理其生命周期。UStruct 为纯旧式数据类型。它们拥有 UObject 反射支持,以便在虚幻编辑器、蓝图操作、序列化和网络通信中进行编辑。
反射系统:
UE4 使用其自身的反射实现,可启用动态功能,如垃圾回收、序列化、网络复制和蓝图/C++ 通信。这些功能为选择加入,意味着您需要为类型添加正确的标记,否则引擎将无视类型,不生成反射数据。
UCLASS() - 告知虚幻引擎生成类的反射数据。类必须派生自 UObject。常用说明符如下:
Blueprintable - 此类可由蓝图延展。
BlueprintReadOnly - 此属性只可从蓝图读取,不可写入。
Category - 定义此属性出现在编辑器 Details 视图下的部分。用于组织。
BlueprintCallable - 可从蓝图调用此函数。
USTRUCT()
4000
- 告知虚幻引擎生成结构体的反射数据。UFUNCTION 说明符列表GENERATED_BODY() - UE4 使用它替代为类型生成的所有必需样板文件代码。UPROPERTY() - 使 UCLASS 或 USTRUCT 的成员变量可用作 UPROPERTY。UPROPERTY 用途广泛。它允许变量被复制、被序列化,并可从蓝图中进行访问。垃圾回收器还使用它们来追踪对 UObject 的引用数。UPROPERTY 说明符列表UFUNCTION() - 使 UCLASS 或 USTRUCT 的类方法可用作 UFUNCTION。UFUNCTION 允许类方法从蓝图中被调用,并在其他资源中用作 RPC。UFUNCTION 说明符列表
UCLASS() 范例:#include "MyObject.generated.h"
UCLASS(Blueprintable)
class UMyObject : public UObject
{
GENERATED_BODY()
public:
MyUObject();
UPROPERTY(BlueprintReadOnly, EditAnywhere)
float ExampleProperty;
UFUNCTION(BlueprintCallable)
void ExampleFunction();
};首先注意 - “MyClass.generated.h”文件已包含。虚幻引擎将生成所有反射数据并将放入此文件。必须在声明类型的头文件中将此文件作为最后的 include 包含。同时可以在标记上添加额外的说明符,通过说明符可对类型拥有的特定行为进行说明。
类命名前缀
虚幻引擎为您提供在构建过程中生成代码的工具。这些工具拥有一些类命名规则。如命名与规则不符,将触发警告或错误。下方的类前缀列表说明了命名的规则。派生自 Actor 的类前缀为 A,如 AController。派生自 对象 的类前缀为 U,如 UComponent。
枚举 的前缀为 E,如 EFortificationType。
接口 类的前缀通常为 I,如 IAbilitySystemInterface。
模板 类的前缀为 T,如 TArray。
派生自 SWidget(Slate UI)的类前缀为 S,如 SButton。
其余类的前缀均为 字母 F ,如 FVector。
数字类型
因为不同平台基础类型的尺寸不同,如 short、int 和 long,UE4 提供了以下类型,可用作替代品:int8/uint8 :8 位带符号/不带符号 整数int16/uint16 :16 位带符号/不带符号 整数
int32/uint32 :32 位带符号/不带符号 整数
int64/uint64 :64 位带符号/不带符号整数
标准 浮点 (32-bit) 和 双倍(64-bit)类型也支持浮点数。UE4有一个模板 TNumericLimits,用于找到数值类型支持的最小和最大范围。如需了解详情,请查阅此 链接 。
字符串
UE4 提供多个不同类使用字符串,可满足多种需求。完整要点:字符串处理FString
FString 是一个可变字符串,类似于 std::string。FString 拥有许多方法,便于简单地使用字符串。使用 TEXT() 宏可新建一个 FString:FString MyStr = TEXT("Hello, Unreal 4!").完整要点:FString APIFText
FText 与 FString 相似,但用于本地化文本。使用 NSLOCTEXT 宏可新建一个 FText。此宏拥有默认语言的命名空间、键和一个数值。FText MyText = NSLOCTEXT("Game UI", "Health Warning Message", "Low Health!")也可使用 LOCTEXT 宏,只需要在每个文件上定义一次命名空间。确保在文件底层取消它的定义
// 在 GameUI.cpp 中 #define LOCTEXT_NAMESPACE "Game UI" //... FText MyText = LOCTEXT("Health Warning Message", "Low Health!") //... #undef LOCTEXT_NAMESPACE // 文件末端//FString到FText的转换示例:
FText WidgetText = FText::Format(
LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"),
FText::FromString(TEXT("FtestPluginModule::OnSpawnPluginTab")),
FText::FromString(TEXT("testPlugin.cpp"))
);
完整要点:FText API
FName
FName 将经常反复出现的字符串保存为辨识符,以便在对比时节约内存和 CPU 时间。FName 不会在引用完整字符串的每个对象间对其进行多次保存,而是使用一个映射到给定字符串的较小存储空间 索引。这会单次保存字符串内容,在字符串用于多个对象之间时节约内存。检查 NameA.Index 是否等于 NameB.Index 可对两个字符串进行快速对比,避免对字符串中每个字符进行相等性检查。完整要点:FName APITCHAR
TCHARs 用于存储不受正在使用的字符集约束的字符。平台不同,它们也可能存在不同。UE4 字符串在后台使用 TCHAR 阵列将数据保存在 UTF-16 编码中。使用返回 TCHAR 的重载解引用运算符可以访问原始数据。完整要点:角色编码部分函数会需要它。如 FString::Printf,‘%s’ 字符串格式说明符需要 TCHAR,而非 FString。
FString Str1 = TEXT("World"); int32 Val1 = 123; FString Str2 = FString::Printf(TEXT("Hello, %s! You have %i points."), *Str1, Val1);FChar 类型提供一个静态效用函数集,以便使用单个 TCHAR。
TCHAR Upper('A'); TCHAR Lower = FChar::ToLower(Upper); // 'a'FChar 类型被定义为 TChar(因其列在 API 中)。完整要点:TChar API
容器
容器也是类,它们的主要功能是存储数据集。常见的类有 TArray、TMap 和 TSet。它们的大小均为动态,因此可变为所需的任意大小。完整要点:组件 APITArray
在这三个容器中,虚幻引擎 4 使用的主要容器是 TArray。它的作用和 std::vector 相似,但却多出许多功能。以下是一些常规操作:TArray<AActor*> ActorArray = GetActorArrayFromSomewhere(); // 告知当前 ActorArray 中保存的元素(AActors)数量。 int32 ArraySize = ActorArray.Num(); // TArrays 从零开始(第一个元素在索引 0 处) int32 Index = 0; // 尝试获取在给定索引处的元素 TArray* FirstActor = ActorArray[Index]; // 在阵列末端添加一个新元素 AActor* NewActor = GetNewActor(); ActorArray.Add(NewActor); // 只有元素不在阵列中时,才在阵列末端添加元素 ActorArray.AddUnique(NewActor); // 不会改变阵列,因为 NewActor 已被添加 // 移除阵列中所有 NewActor 实例 ActorArray.Remove(NewActor); // 移除特定索引处的元素 // 索引上的元素将被下调一格,以填充空出的位置 ActorArray.RemoveAt(Index); // RemoveAt 的高效版,但无法保持元素的排序 ActorArray.RemoveAtSwap(Index); // 移除阵列中的所有元素 ActorArray.Empty();TArray 还有一个额外好处 - 可使其元素被垃圾回收。这将假定 TArray 被标记为 UPROPERTY,并存储 UObject 派生的指针。
UCLASS() class UMyClass :UObject { GENERATED_BODY(); // ... UPROPERTY() TArray<AActor*> GarbageCollectedArray; };之后章节中我们将深度讨论垃圾回收。完整要点:TArrays完整要点:TArray API
TMap
TMap 是键值对的合集,与 std::map 相似。TMap 可基于元素的键快速寻找、添加、并移除元素。只要键拥有为其定义的 GetTypeHash函数(稍后对此进行了解),即可使用任意类型的键。假设您创建了一个基于网格的桌面游戏,需要保存并询问每个方格上的块。通过 TMap 即可轻松完成。如棋盘尺寸较小且保持不变,还存在更加高效的处理方式。enum class EPieceType { King, Queen, Rook, Bishop, Knight, Pawn }; struct FPiece { int32 PlayerId; EPieceType Type; FIntPoint Position; FPiece(int32 InPlayerId, EPieceType InType, FIntVector InPosition) : PlayerId(InPlayerId), Type(InType), Position(InPosition) { } }; class FBoard { private: // 使用 TMap 时可通过块的位置对其进行查阅 TMap<FIntPoint, FPiece> Data; public: bool HasPieceAtPosition(FIntPoint Position) { return Data.Contains(Position); } FPiece GetPieceAtPosition(FIntPoint Position) { return Data[Position]; } void AddNewPiece(int32 PlayerId, EPieceType Type, FIntPoint Position) { FPiece NewPiece(PlayerId, Type, Position); Data.Add(Position, NewPiece); } void MovePiece(FIntPoint OldPosition, FIntPoint NewPosition) { FPiece Piece = Data[OldPosition]; Piece.Position = NewPosition; Data.Remove(OldPosition); Data.Add(NewPosition, Piece); } void RemovePieceAtPosition(FIntPoint Position) { Data.Remove(Position); } void ClearBoard() { Data.Empty(); } };完整要点:TMaps完整要点:TMap API
TSet
TSet 保存唯一值的合集,与 std::set 相似。TArray 通过 AddUnique 和 Contains 方法可用作集。然而 TSet 可更快实现这些操作,但无法像 TArray 那样将它们用作 UPROPERTY。TSet 不会像 TArray 那样将元素编入索引。TSet<AActor*> ActorSet = GetActorSetFromSomewhere(); int32 Size = ActorSet.Num(); // 如集尚未包含元素,则将其添加到集 AActor* NewActor = GetNewActor(); ActorSet.Add(NewActor); // 检查元素是否已包含在集中 if (ActorSet.Contains(NewActor)) { // ... } // 从集移除元素 ActorSet.Remove(NewActor); // 从集移除所有元素 ActorSet.Empty(); // 创建包含 TSet 元素的 TArray TArray<AActor*> ActorArrayFromSet = ActorSet.Array();完整要点:TSet API需注意:TArray 是当前唯一能被标记为 UPROPERTY 的容器类。这意味着无法复制、保存其他容器类,或对其元素进行垃圾回收。
容器迭代器
使用迭代器可在容器的每个元素上进行循环。以下是使用 TSet 的迭代器语法范例。void RemoveDeadEnemies(TSet<AEnemy*>& EnemySet) { // 从集的开头开始迭代到集的末端 for (auto EnemyIterator = EnemySet.CreateIterator(); EnemyIterator; ++EnemyIterator) { // * 运算符获得当前的元素 AEnemy* Enemy = *EnemyIterator; if (Enemy.Health == 0) { // RemoveCurrent 由 TSets 和 TMaps 支持 EnemyIterator.RemoveCurrent(); } } }可结合迭代器使用的其他支持操作:
// 将迭代器移回一个元素 --EnemyIterator; // 以一定偏移前移或后移迭代器,此处的偏移为一个整数 EnemyIterator += Offset; EnemyIterator -= Offset; // 获得当前元素的索引 int32 Index = EnemyIterator.GetIndex(); // 将迭代器重设为第一个元素 EnemyIterator.Reset();
For-each 循环
迭代器很实用,但如果只希望在每个元素之间循环一次,则可能会有些累赘。每个容器类还支持 for each 风格的语法在元素上进行循环。TArray 和 TSet 返回每个元素,而 TMap 返回一个键值对。// TArray TArray<AActor*> ActorArray = GetArrayFromSomewhere(); for (AActor* OneActor :ActorArray) { // ... } // TSet - 和 TArray 相同 TSet<AActor*> ActorSet = GetSetFromSomewhere(); for (AActor* UniqueActor :ActorSet) { // ... } // TMap - 迭代器返回一个键值对 TMap<FName, AActor*> NameToActorMap = GetMapFromSomewhere(); for (auto& KVP :NameToActorMap) { FName Name = KVP.Key; AActor* Actor = KVP.Value; // ... }注意:auto 关键词不会自动指定指针/引用,需要自行添加。
相关文章推荐
- 黑马程序员-IOS学习笔记-C语言基础其他数据类型及总结
- Java基础学习笔记(十)线程的创建总结
- MySQL学习笔记_关于MySQL的整数类型字段长度知识总结
- 黑马程序员_学习日记2_有关C#基础知识总结归纳之对象和类型
- 嵌入式开发之C基础学习笔记03--基本数据类型,操作符,修饰符等基本概念
- JAVA基础类型范围 ---学习笔记
- VS2010 学习笔记 WF4 (9) 工作流基础总结
- Linux学习总结笔记(一):硬件理论基础
- 【Java学习笔记】基础知识学习1【基本输出,数据类型,基础运算符号】
- 黑马程序员之 ASP.NET学习笔记:ADO.NET基础知识总结
- 【学习笔记三】最基本的JAVA基础[数据类型,运算符]
- java基础学习笔记原始类型变量赋值与非原始变量赋值
- Go学习笔记之基础数据类型
- 嵌入式开发之C基础学习笔记10--总结
- jQuery学习笔记1--基础总结
- C\C++ 程序员从零开始学习Android - 个人学习笔记(四) - java基础 - 数据类型、变量、字符串、数组
- C#学习笔记——面向对象、面向组件以及类型基础
- Java基础学习笔记(一)基本数据类型
- 嵌入式开发之C++基础学习笔记2--总结所有基础用法
- Java基础学习笔记(一)基本数据类型