UE4杂记
一些学习UE4时的笔记,转载请注明出处。
☆ UE4逻辑
Actor 是由 AActor 类派生而来的类实例;能被放入游戏世界场景的所有游戏性对象的基础类。对象是继承自 UObject 类的类实例;虚幻引擎中所有对象的基础类,包括Actor。因此,实际上虚幻引擎中所有的实例均为对象;然而,一般的术语中,Actors通常用于指继承了AActor类的实例,而“对象”指非继承自AActor类的实例。
Pawn 是可以作为世界中的一个“代理”的Actor。Pawn可以由控制器处理,它们可以轻松地接受输入,并且可以执行各种各样的类似于玩家的动作。
Character(角色)是类人的Pawn。
控制器 是负责管理Pawn的Actor。一般有两种控制器:AIController 和PlayerController。
PlayerController(玩家控制器)是Pawn和控制它的人类玩家间的接口。PlayerController本质上代表了人类玩家的意愿。
AIController正如其名,是控制Pawn的一个人工智能控制Pawn的接口。
GameState 包含了游戏状态,这包括像关联玩家的列表、分数、象棋游戏中的象棋位置或者在开放世界游戏中已经完成的任务列表。
PlayerState是游戏中的一个参与者的状态,比如人类玩家或者模拟人类玩家的机器人。
☆ UE4反射
参考:http://www.cnblogs.com/ghl_carmack/p/5677090.html
反射我的理解就是对一些类成员加上一些限制词后,可以在UE4运行的编辑面板上改动参数,并且实时变化。
如:
/* Allows distance-based volume attenuation. */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = AttenuationDistance, meta = (DisplayName = "Enable Volume Attenuation"))
uint8 bAttenuate : 1;
就是可以在细节面板中看到AttenuationDistance的值并且可以进行修改,鼠标放上去后还会有Enable Volume Attenuation的注释,bAttenuate的初始值为1。
反射系统是可以选择加入的。你需要给暴露给反射系统的类型或属性添加注解,这样Unreal Header Tool (UHT)就会在编译工程的时候利用那些信息生成特定的代码。
#include "FileName.generated.h"
为了标记一个头文件包含反射类型,需要在文件顶部添加一个特殊的include文件。
UCLASS()来表明它是需要反射的类型
GENERATED_USTRUCT_BODY()
该段代码在需要反射的类或者结构体里面是必要的,因为它们会加入额外的函数和typedef到类的内部。
UPROPERTY()中包含了EditAnywhere和Category=Pawn注解。这表示这个属性可以在编辑中的任意细节面板中进行编辑,并且会显示在Pawn分类中。如:
/** How many resources this pawn is worth when it dies. */
UPROPERTY(EditAnywhere, Category=Pawn)
int32 ResourcesToGather;
UFUNCTION()有以BlueprintCallable以及分类作为注解的函数,这表示它们可以在蓝图里面调用到这些C++函数:如:
/** set attachment for weapon slot */
UFUNCTION(BlueprintCallable, Category=Attachment)
void SetWeaponAttachment(class UStrategyAttachment* Weapon);
UStruct是所有 聚合结构体的基础类型(包含其它成员的类型,比如一个C++类、结构体、或者函数),不应该跟C++中的结构体(struct)混为一谈(那是UScriptStruct)。UClass可以包含函数、属性以及它们的孩子,而UFunction和UStriptStruct只能包含属性。
☆ UE4的API前缀规范
派生(继承)自 Actor 的类前缀为 A,比如 AController。
派生自 Object 的类前缀为 U,比如 UComponent。
如:USceneComponent(允许子组件相对于父组件进行位移,旋转,缩放等操作的组件),UStaticMeshComponent(静态网格组件),USphereComponent(球体碰撞组件)
派生自 SWidget(Slate UI)的类前缀为 S,比如 SButton
Enums 的前缀为 E,比如 EFortificationType。
Interface 类的前缀通常为 I,比如 IAbilitySystemInterface。
Template 类的前缀为 T,比如 TArray。
其余类的前缀均为 字母 F ,比如 FVector。
☆ UE4类的继承关系
Object->Actor+Component->Level->World->WorldContext->GameInstance->Engine
☆ 虚幻4纯函数和非纯函数
主要的区别是纯函数不会以任何方式修改状态或者类的成员,纯函数一般用于 getter 函数 或者仅输出一个数据值的操作符。而非纯函数可以自由地修改状态。
☆ UE4第三方库调用机制
UE4 被划分为多个模块。每个模块都拥有控制其编译方式的 .build.cs 文件,包括定义模块相依性的选项、额外的库、包含路径等。这些模块被默认编译为 DLL 文件,可通过单一可执行文件进行加载。可选择在 BuildConfiguration.cs 文件中编译一个单块可执行文件。
模块是 UE4 的编译块。引擎作为模块的一个大集合而实现,而游戏则提供其自身的模块进行扩大。每个模块都封装了一套功能,可提供一个公共接口和编译环境(利用宏、包含路径等),以便其他模块使用。
模块通过带 .build.cs 扩展名的 C# 源文件进行声明,保存在项目的 Source 目录下。属于模块的 C++ 源代码保存在 .build.cs 文件旁,或其子目录中。每个 .build.cs 文件声明派生自 ModuleRules 基类的类,并设置属性控制器从构造函数进行编译的方式。这些 .build.cs 文件由虚幻编译工具编译,并被构造来确定整体编译环境。
☆ 代理
代理允许您在C++对象上以通用的但类型安全的方式调用成员函数。通过使用代理,您可以将其动态地绑定到任何对象的成员函数上,然后在该对象上调用函数,即时调用者不知道该对象的类型也没关系。
http://api.unrealengine.com/CHN/Programming/UnrealArchitecture/Delegates/index.html
class FLogWriter
{
void WriteToLog( FString );
};
(第一步,声明宏)要想调用WriteToLog函数,我们需要用宏声明的方法,创建针对该函数签名的代理类型:
DECLARE_DELEGATE_OneParam( FStringDelegate, FString );
这创建了一个称为 'FStringDelegate' 的代理类型,取入一个 'FString' 类型的参数。
(第二步,创建代理对象)如果要在一个类中使用FStringDelegate,调用如下:
class FMyClass
{
FStringDelegate WriteToLogDelegate;
};
这允许FMyClass得以维护一个指向任意一个类的方法,这个类对于该代理类型唯一需要知道的就是它的函数签名WriteToLogDelegate。
(第三步,绑定代理到方法上)若要分配这个代理,首先要创建 'FLogWriter' 类的一个实例LogWriter,然后创建那个'FLogWriter'类对象实例的 'WriteToLog' 方法的代理,从而把一个代理绑定到一个类的方法上
FSharedRef< FLogWriter > LogWriter( new FLogWriter() );
WriteToLogDelegate.BindSP( LogWriter, &FLogWriter::WriteToLog );// 绑定一个基于共享指针的成员函数代理。
(第四步,调用)现在,FMyClass就可以调用FLogWriter 中的‘WriteToLog'方法了,甚至它不需要知道关于 'FLogWriter' 的任何信息。要想调用您的代理,仅需使用 'Execute()' 方法。
WriteToLogDelegate.Execute( TEXT( "Delegates are spiffy!" ) );