UE4初学笔记

匿名 (未验证) 提交于 2019-12-02 23:32:01

开放参数至蓝图

C++中常常使用UE4中的一些宏来设置想要暴露于蓝图的类、属性、方法等。

暴露类

使用UCLASS([specifiers])暴露类至蓝图,其中的specifiers在暴露类的时候并不常用,并在第一行使用GENERATED_BODY(),添加头文件#include "XXX.generated.h",如:

#include "GameFramework/Actor.h" #include "MyActor.generated.h"  UCLASS() class AMyActor : public AActor {     GENERATED_BODY()  public:     // 设置该Actor属性的默认值     AMyActor();      // 每一帧都调用     virtual void Tick( float DeltaSeconds ) override;  protected:     // 游戏开始或产生时调用     virtual void BeginPlay() override; }; 

往往通过在编辑器中“文件 -> 添加C++类 -> 使用类引导选择父类创建类”的方式直接生成对应的模板。

暴露属性

使用UPROPERTY([specifiers])宏暴露属性至蓝图,如:

UPROPERTY([specifier, specifier, ...], [meta(key=value, key=value, ...)]) Type VariableName; 

其中常用的specifier如下:

  • EditAnywhere:可通过“属性”窗口在原型和实例上进行编辑;
  • VisibleAnywhere:该属性在“属性”窗口中可见,但无法编辑,与EditAnywhere不兼容;
  • BlueprintReadWrite:可从蓝图读取或写入此属性;
  • BlueprintReadOnly:此属性在蓝图中只读,表示希望该属性作为常量出现在蓝图中;
  • Category=“XXX”:给该属性分类以便在虚幻编辑器中查询;

此处注意EditAnyWhere和BlueprintReadWrite的区别,前者表示在虚幻编辑器中可以在“属性”窗口中对该属性值进行编辑。然而若需要在蓝图脚本编辑器中设置该属性,则需要使用BlueprintReadWrite,相当于为该属性自动添加了get和set方法。

暴露函数

使用UPROPERTY([specifiers])宏暴露属性至蓝图,如:

UFUNCTION([specifier, specifier, ...], [meta(key=value, key=value, ...)]) ReturnType FunctionName([Parameter, Parameter, ...]) 

其中常用的specifier如下:

  • BlueprintCallable:表示此函数可以直接在蓝图中执行,函数的实现只能在C++中进行;
  • BlueprintImplementableEvent:该函数的具体实现只能在蓝图中进行。对于没有返回值的函数,可以当做一种事件来处理,不必有具体的实现。而对于有返回值的函数,则需要在蓝图编辑器中的左边栏查找该函数并进行覆写。其调用还只能在C++原生代码中进行;
  • BlueprintNativeEvent:蓝图可以调用该函数,该函数的默认实现在C++中已经完成了,但是蓝图可以对该函数进行覆盖重写。这个参数可以实现最灵活的函数调用;

注意:对于BlueprintNativeEvent函数,需要一些特殊处理:

  • 首先,要声明一个新的虚函数,函数名为 FunctionName_Implementation;
  • 其次,对该函数的C++实现要转而对该虚函数进行;
  • 最终,无论C++或者蓝图调用该函数时,都是直接使用函数的原名。

Example:

// header file UFUNCTION(BlueprintNativeEvent) void CountdownHasFinished(); virtual void CountdownHasFinished_Implementation();  // cpp source file void ACountdown::CountdownHasFinished_Implementation() {     CountdownText->SetText(TEXT(“Go!)); }  void ACountdown::BeginPlay() {     Super::BeginPlay();     CountdownHasFinished(); } 

暴露结构体

游戏性类中的UStruct可包含变量,包括UProperty变量、函数和运算符。结构体的声明发生在类的声明之前。使用UStruct,不必继承自任何特定类,只需用USTRUCT(specifiers)标记该结构体,如:

USTRUCT([Specifier, Specifier, ...]) struct StructName {     GENERATED_USTRUCT_BODY()      UPROPERTY([specifier, specifier, ...], [meta(key=value, key=value, ...)])         Type VariableName;      UFUNCTION([specifier, specifier, ...], [meta(key=value, key=value, ...)])     ReturnType FunctionName([Parameter, Parameter, ...]) }; 

其中Specifier往往也就只用BlueprintType,表示结构体可以在蓝图中使用。

与UObject不同的是,UStruct不会被垃圾回收,必须自行管理其生命周期。UStruct应该是纯传统数据类型,包含UObject反射支持,可以在虚幻编辑器、蓝图操控、序列化、联网等中编辑。

代理

使用代理类似函数指针,可以以通用的但类型安全的方式调用成员函数。通过使用代理,并将其动态地绑定到任何对象的成员函数上,然后在该对象上调用函数,即使调用者不知道该对象的类型也没关系。

与标记为BlueprintImplementableEvent的UFUNCTION类似,但是UFUNCTION仅仅能在蓝图中覆写,却无法在蓝图中调用。即无法通过蓝图中的某些事件去触发。而代理则可以绑定至不同类型的事件/流程,并实现不同的流程。

单播代理和多播代理区别

单播代理仅仅能绑定一个函数,而多播代理却可以绑定多个函数。单播代理可以代理有返回值的函数,而多播代理不可以代理有返回值的函数。

绑定时单播代理使用BindXXX()等方法。根据要绑定的函数类型的不同使用不同的方法,如绑定全局函数使用BindRaw(),绑定静态函数使用BindStatic()等等。由于是单播代理,故仅能绑定一个函数,以最后绑定的函数为准。详见官方文档。常用绑定UObject方法,如:

this->StringDelegateWithoutPar.BindUObject(this, &AActorPluginDemo::FuncForDelegateNoPar); 

多播代理进行绑定时则采用AddXXX()等方法。与单播代理类似。

单播代理最终使用Execute()ExecuteIfBound()执行,其中后者更安全。但要注意若有返回值,则只能使用Execute()来获取返回值。最好之前使用IsBound()确认是否已经绑定有函数。多播代理则使用Broadcast()广播所有的参数。

动态代理和非动态代理的区别

动态代理可以用于Blueprint中,而非动态代理仅能在C++中进行绑定。注意声明方式的区别!

// 声明非动态代理不需要添加参数名称 DECLARE_DELEGATE_TwoParams(DelegateName, Param1Type, Param2Type);  // 声明动态代理则需要添加参数名称 DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(DynamicDelegateName, Param1Type, Param1Name, Param1Type, Param2Name); 

为了动态代理能够在Blueprint中使用,则自然需要在声明对应的变量的时候添加UPROPERTY([specifiers])。其中可用于多播代理的Specifier有BlueprintAssignable、BlueprintAuthorityOnly、BlueprintAuthorityOnly、
BlueprintCallable几种,详见官方文档

之后就可以在蓝图中对该动态代理变量进行绑定,并对其实现不同的业务流程。

使用代理多播TArray

若想使用代理多播TArray到蓝图中,则参数类型必须为TArray的引用,而且要加上const关键字,否则蓝图中会报错,如:

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(DynamicDelegateName, const TArray<FSelfDefinedStruct>&, StructArray); 

同样地,蓝图可调用函数中的参数若为TArray,也需要使用TArray的const引用,如:

UFUNCTION(BlueprintCallable) void function(int32 par1, const TArray<FString>& strArr); 

参考资料

文章来源: https://blog.csdn.net/mrliuzhao/article/details/90266863
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!