以下为《UE4学习笔记(函数声明周期,委托与事件,反射机制)》的无排版文字预览,完整内容请下载
函数声明周期:
GameInstance::Init //创建世界 World 将World保存进GameInstance中的结构体WorldContext中
LevelScriptActor::Construct //创建Level,LevelScriptActor
MyActor::Construct //MyActor是已经存在场景中的Actor(即编辑器模式下创建的)
GameMode::Construct //WorldSetting绑定的框架运行
MyActor::PostInitializeComponents //Actor所有组件初始化(UActorComponent::InitializeComponent)调用完后调用的函数
LevelScriptActor::PostInitializeComponents
GameMode::PostInitializeComponents
Controller::Construct
Controller::PostInitializeComponents
HUD::NativeConstruct
HUD::PostInitializeComponents
Character::Construct
Character::PostInitializeComponents
MyActor::BeginPlay
GameMode::BeginPlay
LevelScriptActor::BeginPlay
Controller::BeginPlay
HUD::BeginPlay
UserWidget::Construct
UserWidget::Initialize (相当于PostInitializeComponents)
Character::BeginPlay
Controller::Tick
MyActor::Tick
LevelScriptActor::Tick
Character::Tick
HUD::Tick
UserWidget::Tick?
?
Tips
AActor::PreInitializeComponents //Actor组件初始化前调用的函数
->UActorComponent::InitializeComponent //Actor组件初始化
->Aactor::PostInitializeComponnet //Actor所有组件初始化调用完后调用的函数
?
总结:
Construct->PostInitializeComponents->BeginPlay->Tick
委托与事件
单播与多播
http://api.unrealengine.com/CHN/Programming/UnrealArchitecture/Delegates/index.html
?
利用委托可以泛型但类型安全的方式在C++对象上调用成员函数。可使用委托动态绑定到任意对象的成员函数,然后在该对象上调用函数,即使调用程序不知对象类型也可进行操作
复制委托对象绝对安全。可利用值传递委托,但其须在堆上分配内存,因此通常并不推荐此操作。应尽量固定利用引用传递委托。
同时支持单某某和多投射委托,及可安全序列化到硬盘的“动态”委托。
单某某
多投射
事件
动态(UObject, serializable)
声明委托
使用提供的声明宏之一来声明委托。所用宏由要绑定到委托的函数的签名决定。系统预定义各种泛型函数签名组合,可在从中声明委托类型、填充返回值及所需参数类型的类型名。当前支持以下使用任意组合的委托签名:
返回值的函数
最多4个“负载”变量
最多8个函数参数
声明为“const”的函数
使用此表格查找要用于声明委托的生命宏。
函数签名
声明宏
void Function()
DECLARE_DELEGATE( DelegateName )
void Function( )
DECLARE_DELEGATE_OneParam( DelegateName, Param1Type )
void Function( , )
DECLARE_DELEGATE_TwoParams( DelegateName, Param1Type, Param2Type )
void Function( , , ...)
DECLARE_DELEGATE_Params( DelegateName, Param1Type, Param2Type, ...)
Function()
DECLARE_DELEGATE_RetVal( RetValType, DelegateName )
Function( )
DECLARE_DELEGATE_RetVal_OneParam( RetValType, DelegateName, Param1Type )
Function( , )
DECLARE_DELEGATE_RetVal_TwoParams( RetValType, DelegateName, Param1Type, Param2Type )
Function( , , ...)
DECLARE_DELEGATE_RetVal_Params( RetValType, DelegateName, Param1Type, Param2Type, ...)
同时还提供以上宏的变体,用于多投射、动态和包裹委托:
DECLARE_MULTICAST_DELEGATE...
DECLARE_DYNAMIC_DELEGATE...
DECLARE_DYNAMIC_MULTICAST_DELEGATE...
DECLARE_DYNAMIC_DELEGATE...
DECLARE_DYNAMIC_MULTICAST_DELEGATE...
委托签名声明可存在于全局作用域、在命名空间,甚至是类声明中(但无法存在于函数主体中)。
参见%Programming/UnrealArchitecture/Delegates/Dynamic:title% and?多播委托,了解声明此类委托的更多相关信息。
绑定委托
委托系统理解某些类型的对象,使用此类对象时将启用附加功能。将委托绑定到UObject或共享指针类的成员,委托系统可保留对该对象的弱引用,因此对象在委托下方被销毁时,可通过调用?IsBound()?或?ExecuteIfBound()?函数进行处理。注意各类受支持对象的特殊绑定语法。
函数
描述
Bind()
绑定到现有委托对象。
BindStatic()
绑定原始C++指针全局函数委托。
BindRaw()
绑定原始C++指针委托。原始指针不使用任何类型的引用,因此如对象在委托下方被删除,引用原始指针可能不安全。需谨慎调用Execute()!
BindSP()
绑定基于指针的共享成员函数委托。共享指针委托会保留对对象的弱引用。可使用?ExecuteIfBound()?进行调用。
BindUObject()
绑定基于UObject的成员函数委托。UObject委托会保留对对象的弱引用。可使用?ExecuteIfBound()?进行调用。
UnBind()
取消绑定此委托。
参见?DelegateSignatureImpl.inl(位于?..\UE4\Engine\Source\Runtime\Core\Public\Templates\),了解此类函数的变体、参数和实现。
负载数据
绑定到委托时,可同时传递负载数据。其为调用时被直接传到绑定函数的任意变量。此操作十分有用,利用其可在绑定时将参数存储在委托内。所有委托类型(除“动态”外)均自动支持负载变量。此范例将两个自定义变量(一个布尔,一个int32)传递到委托。之后调用该委托时,此类参数将被传到绑定函数。须始终接受委托类型参数后的额外变量参数。
MyDelegate.BindRaw( &MyFunction, true, 20 );
执行委托
通过调用委托的?Execute()?函数执行绑定到委托的函数。执行前须检查委托是否已绑定。此操作是为了使代码更安全,因为有时委托可能含有未初始化且被后续访问的返回值和输出参数。执行未绑定的委托在某些情况下确实可能导致内存混乱。可调用?IsBound()?检查是否可安全执行委托。同时,对于无返回值的委托,可调用ExecuteIfBound(),但需注意输出参数可能未初始化。
?
执行函数
描述
Execute()
?
ExecuteIfBound()
?
IsBound()
?
参见多播委托,了解执行多投射委托的相关细节。
用法示例
假设类拥有可在任何地方随意调用的方法:
class FLogWriter{ void WriteToLog( FString );};
要调用WriteToLog函数,需创建该函数签名的委托类型。为此,首先需使用以下宏声明委托。例如,以下是一个简单的委托类型:
DECLARE_DELEGATE_OneParam( FStringDelegate, FString );
此将创建名为“FStringDelegate”的委托类型,该类型使用“FString”类型的单个参数。
此为在类中使用此“FStringDelegate”的方法范例:
class FMyClass{ FStringDelegate WriteToLogDelegate;};
利用此操作,类可保有指向任意类中的方法的指针。该类唯一真正了解的信息就是,此委托是其的函数签名。
如要分配委托,现在只需创建委托类的实例,将拥有该方法的类作为模板参数传递。同时还需传递对象的实例和方法的实际函数地址。因此,现在需创建“FLogWriter”类的实例,然后创建改对象实例"WriteToLog"方法的委托。
TSharedRef< FLogWriter > LogWriter( new FLogWriter() );
WriteToLogDelegate.BindSP( LogWriter, &FLogWriter::WriteToLog );
此操作可将委托动态绑定到类的方法!很简单,对吧?
注意:绑定到的对象由共享指针拥有,因此?BindSP?的SP部分代表共享指针。此外,还有不同对象类型的版本,例如BindRaw()和BindUObject()。
FMyClass现在可调用“WriteToLog”方法,甚至无需了解“FLogWriter”类的任何信息!要调用委托,只需使用“Execute()”方法:
WriteToLogDelegate.Execute( TEXT( "Delegates are spiffy!") );
如将函数绑定到网络前调用Execute(),将触发断言:多数情况下,建议进行以下操作:
WriteToLogDelegate.ExecuteIfBound( TEXT( "Only executes if a function was bound!") );
?
?
?
?
?
?
?
?
?
?
?
普通的动态
http://api.unrealengine.com/CHN/Programming/UnrealArchitecture/Delegates/Dynamic/index.html
?
动态代理可以进行序列化,可以通过名称查找它们函数,其执行速度比常规代理慢。
声明动态代理
动态代理的声明方式和声明标准代理一样,只是它们使用针对于动态代理的宏变种。
声明宏
描述
DECLARE_DYNAMIC_DELEGATE[_Const, _RetVal, etc.]( DelegateName )
创建一个动态代理。
DECLARE_DYNAMIC_MULTICAST_DELEGATE[_Const, _RetVal, etc.]( DelegateName )
创建一个动态的多播代理。
DECLARE_DYNAMIC_DELEGATE[_Const, _RetVal, etc.]( DelegateName )
创建一个封装的动态代理。
DECLARE_DYNAMIC_MULTICAST_DELEGATE[_Const, _RetVal, etc.]( DelegateName )
创建一个封装的动态多播代理。
动态代理绑定
辅助宏
描述
BindDynamic( UserObject, FuncName )
在动态代理上调用BindDynamic()的辅助宏。自动生成函数名称字符串。
AddDynamic( UserObject, FuncName )
在动态多播代理上调用AddDynamic()的辅助宏。自动生成函数名称字符串。
RemoveDynamic( UserObject, FuncName )
在动态多播代理上调用RemoveDynamic()的辅助宏。自动生成函数名称字符串。
执行动态代理
[INCLUDE:Programming/UnrealArchitecture/Delegates#ExecutingDelegates]
封装的动态代理
动态代理声明时可以具有一个执行该代理的封装器代理方法。
声明宏
描述
DECLARE_DYNAMIC_DELEGATE[_Const, _RetVal, etc.]( DelegateName )
创建一个封装的动态代理。
DECLARE_DYNAMIC_MULTICAST_DELEGATE[_Const, _RetVal, etc.]( DelegateName )
创建一个封装的动态多播代理。
反射机制(重点)
UCLASS()?
告知虚幻引擎生成类的反射数据。类必须派生自 UObject。
?
USTGENERATED_BODYRUCT()?
告知虚幻引擎生成结构体的反射数据。
?
()?
UE4 使用它替代为类型生成的所有必需样板文件代码。
?
UPROPERTY()?
使 UCLASS 或 USTRUCT 的成员变量可用作 UPROPERTY。UPROPERTY 用途广泛。它允许变量被复制、被序列化,并可从蓝图中进行访问。垃圾回收器还使用它们来追踪对 UObject 的引用数。
?
UFUNCTION()?
使 UCLASS 或 USTRUCT 的类方法可用作 UFUNCTION。UFUNCTION 允许类方法从蓝图中被调用,并在其他资源中用作 RPC。
?
UENUM()
创建可以被蓝图调用的enum反射。该类必须继承自uint8。
UENUM(Blueprintable,BlueprintType)
STRUCT(Blueprintable,BlueprintType)
UCLASS(Blueprintable,BlueprintType)
Blueprintable: 可以用蓝图继承该类
BlueprintType: 在其他蓝图中可以把这个继承蓝图类当成一个变量类型
添加了BlueprintType的枚举,结构体,Class 才能在DataTable识别出来
?
官网:: http://api.unrealengine.com/CHN/Programming/Introduction/index.html
?
?
?
?
UPROPERTY/UFUNCTION
EditAnywhere:能被编辑,EditAnywhere的范围是本类蓝图Details面板 以及 放入场景中的Actor?的Details面板
EditDefaultsOnly: 只能在蓝图Details面板中编辑(只能更改蓝图Details面板),游戏运行过程中不能更改
EditInstanceOnly: 只有在拖拽到场景种的的编辑界面(只能更改实例Details面板)
?
VisibleAnywhere:能被任何地方显示(无法被编辑)
?
BlueprintReadOnly:在蓝图中可get
BlueprintReadWrite:在蓝图中可set也可get
?
private:
UPROPERTY(BlueprintGetter = GetGenerateOverlapEvents,BlueprintSetter = SetGenerateOverlapEvents)
uint8 bGenerateOverlapEvents : 1;
?
?
BlueprintAssignable: 只用来修饰委托变量,在蓝图种实现委托事件
?
?
Replicated:属性网络间可复制
ReplicatedUsing:属性除了可以网络复制外,当属性值发生改变时可以触发一个函数,例如:
UPROPERTY(ReliabledUsing=OnMyFunction)
int Num;
UFUNCTION()
void OnMyFunction(var OldVar); //要加UFUNCTION()
Reliable:函数网络间进行复制,并会忽略带宽或网络错误而被确保送达。仅在与客户端或服务器共同使用时可用
UnReliable:函数网络间进行复制,但可能会由于带宽限制或网络错误而传送失败。仅在与客户端或服务器一起使用时有效
?
WithValidation:声明一个名为与main函数相同的附加函数,但将_Validation添加到最后。该函数采用相同的参数,并返回一个布尔值来指示是否应该继续调用主函数
?
Instanced:
实例对象 例如:UPROPERTY(Instanced)
Transient:
暂存,临时存在 例如:UPROPERTY(Transient)
?
Server:此函数仅在服务器上执行。提供一个名称为[FunctionName]_Implementation的函数主体,而不是[FunctionName]; 自动生成的代码将包含一个转换程序来在需要时调用实现方法
Client:此函数仅在该函数从属对象所从属的客户端上执行。提供一个名称为[FunctionName]_Implementation的函数主体,而不是[FunctionName]; 自动生成的代码将包含一个转换程序来在需要时调用实现方法
?
CallInEditor:函数可以在编辑器中通过详细信息面板中的按钮在选定实例中调用
BlueprintCallable: 蓝图可以调用C++方法
meta = (WorldContext = "Obj", CallableWithoutWorldContext):静态函数调用省略UObject* Obj参数
BlueprintImplementa 内容过长,仅展示头部和尾部部分文字预览,全文请查看图片预览。 String("xyz123");
FunThreeParam.Count = 675;
//UFunction* Function=SrcObj->FindFunctionChecked(FName("UFunThree"));
//SrcObj->ProcessEvent(Function,FunThreeParam);
SrcObj->ProcessEvent(FunThree, &FunThreeParam); //执行委托
//获取返回值地址
uint8* RetValPtr = (uint8*)&FunThreeParam + FunThree->ReturnValueOffset;
//通过返回值地址 得到返回值所对应的值
int32* RetVal=(int32*)RetValPtr;
DEBUG("ASrcActor->UFunThree Return Value: "+FString::FromInt(*RetVal)+" FunThreeParam.Count: "+FString::FromInt(FunThreeParam.Count));
}
}
[文章尾部最后500字内容到此结束,中间部分内容请查看底下的图片预览]请点击下方选择您需要的文档下载。
以上为《UE4学习笔记(函数声明周期,委托与事件,反射机制)》的无排版文字预览,完整内容请下载
UE4学习笔记(函数声明周期,委托与事件,反射机制)由用户“yongkim”分享发布,转载请注明出处