本文共 5705 字,大约阅读时间需要 19 分钟。
委托机制是 UE4 提供的一种强大的功能,允许我们将函数的执行权转移给其他组件或对象。这种机制在游戏开发中非常有用,尤其是在需要扩展或模块化代码时。
委托可以分为多种类型,包括:
void UDelegateObject::TestDelegate() { UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__));}
FTestDelegate& UDelegateMaker::MakeDelegate(EDelegateType Type) { if (Delegate.IsBound()) { Delegate.Unbind(); } switch (Type) { case EDelegateType::Object: if (UEObject == nullptr) { UEObject = NewObject(); } Delegate.BindUObject(UEObject, &UDelegateObject::TestDelegate); break; }}
void ADelegateInvoker::InvokeDelegate(EDelegateType Type) { if (Maker == nullptr) { Maker = NewObject(); Maker->MakeDelegate(Type).ExecuteIfBound(); } else { Maker->MakeDelegate(Type).ExecuteIfBound(); }}
多线程编程在游戏开发中非常重要,尤其是在需要同时处理复杂任务时。UE4 提供了丰富的多线程支持工具和功能。
依赖关系结构体用于定义任务之间的依赖关系,确保任务按正确顺序执行。
USTRUCT(BlueprintType) struct FMyTaskItem { GENERATED_USTRUCT_BODY()public: UPROPERTY(BlueprintReadWrite) FString TaskName; FString TaskName; FGraphEventRef GraphEvent; TGraphTask* GraphTask; FMyTaskItem() : TaskName(TEXT("NoName")), GraphEvent(nullptr), GraphTask(nullptr) {} FMyTaskItem(FString Name, FGraphEventRef EventRef = FGraphEventRef()) : TaskName(Name), GraphEvent(EventRef), GraphTask(nullptr) {} FMyTaskItem(FString Name, TGraphTask* Task = nullptr) : TaskName(Name), GraphEvent(nullptr), GraphTask(Task) {} ~FMyTaskItem() { GraphEvent = nullptr; }};
任务类用于定义任务的具体行为和执行方式。
class FJustPrintTask { FString TaskName; TArrayChildEvents; AActor* TaskOwner;public: FJustPrintTask(FString Name, TArray Events, AActor* Actor) : TaskName(Name), ChildEvents(Events), TaskOwner(Actor) {} ~FJustPrintTask() {} FORCEINLINE TStatId GetStatId() const { RETURN_QUICK_DECLARE_CYCLE_STAT(FJustPrintTask, STATGROUP_TaskGraphTasks); } static ENamedThreads::Type GetDesiredThread() { return ENamedThreads::AnyThread; } static ESubsequentsMode::Type GetSubsequentsMode() { return ESubsequentsMode::TrackSubsequents; } void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { UE_LOG(LogTemp, Log, TEXT(__FUNCTION__ " %s:Begin"), *TaskName); for (TGraphTask* Task : ChildEvents) { if (Task) { Task->Unlock(); MyCompletionGraphEvent->DontCompleteUntil(Task->GetCompletionEvent()); } } MyCompletionGraphEvent->DontCompleteUntil(TGraphTask::CreateTask().ConstructAndDispatchWhenReady(TaskName, TaskOwner)); UE_LOG(LogTemp, Log, TEXT(__FUNCTION__ " %s:End"), *TaskName); }}
报告任务用于在任务完成时触发特定事件。
class FReportTask { FString TaskName; AActor* TaskOwner;public: FReportTask(FString Name, AActor* Actor) : TaskName(Name), TaskOwner(Actor) {} ~FReportTask() {} FORCEINLINE TStatId GetStatId() const { RETURN_QUICK_DECLARE_CYCLE_STAT(FReportTask, STATGROUP_TaskGraphTasks); } static ENamedThreads::Type GetDesiredThread() { return ENamedThreads::GameThread; } static ESubsequentsMode::Type GetSubsequentsMode() { return ESubsequentsMode::TrackSubsequents; } void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { AMyTaskGraphActor* Actor = Cast(TaskOwner); if (IsValid(Actor)) { Actor->OnTaskComplete(TaskName); } }}
Actor 类用于管理任务执行。
UCLASS() class UECPP_API AMyTaskGraphActor : public AActor { GENERATED_BODY()public: AMyTaskGraphActor(); FMyTaskItem CreateTask(FString TaskName, const TArray& Prerequisites, const TArray & ChildTasks, bool DispatchWhenReady = true); FMyTaskItem CreateTaskPure(FString TaskName, bool DispatchWhenReady = true) { return CreateTask(TaskName, Empty, Empty, DispatchWhenReady); } FMyTaskItem CreateTaskWithPrerequisitesOnly(FString TaskName, const TArray & Prerequisites, bool DispatchWhenReady = true) { return CreateTask(TaskName, Prerequisites, Empty, DispatchWhenReady); } FMyTaskItem CreateTaskWithChildTasksOnly(FString TaskName, const TArray & ChildTasks, bool DispatchWhenReady = true) { return CreateTask(TaskName, Empty, ChildTasks, DispatchWhenReady); } UFUNCTION(BlueprintCallable) void FireTask(const FMyTaskItem& Task); UFUNCTION(BlueprintImplementableEvent) void OnTaskComplete(const FString& TaskName);}
任务执行需要按照依赖关系顺序完成。
void FJustPrintTask::DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { UE_LOG(LogTemp, Log, TEXT(__FUNCTION__ " %s:Begin"), *TaskName); for (TGraphTask* Task : ChildEvents) { if (Task) { Task->Unlock(); MyCompletionGraphEvent->DontCompleteUntil(Task->GetCompletionEvent()); } } MyCompletionGraphEvent->DontCompleteUntil(TGraphTask::CreateTask().ConstructAndDispatchWhenReady(TaskName, TaskOwner)); UE_LOG(LogTemp, Log, TEXT(__FUNCTION__ " %s:End"), *TaskName);}
void AMyTaskGraphActor::FireTask(const FMyTaskItem& Task) { if (Task.GraphTask) { UE_LOG(LogTemp, Log, TEXT("Task[%s] Fire."), *Task.TaskName)); Task.GraphTask->Unlock(); }}
通过以上内容,可以看出 UE4 提供了强大的任务和委托系统,能够有效管理复杂任务流程和依赖关系。
转载地址:http://ibuh.baihongyu.com/