Update directive utilities plugin

This commit is contained in:
2026-08-15 21:06:43 +02:00
parent 2fe7f83a38
commit a06fed1cba
103 changed files with 18211 additions and 1071 deletions

View File

@@ -0,0 +1,48 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "Engine/CancellableAsyncAction.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "DirectiveUtilAsyncActionBase.generated.h"
UCLASS(Abstract)
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilAsyncActionBase : public UBlueprintAsyncActionBase
{
GENERATED_BODY()
public:
virtual void RegisterWithGameInstance(const UObject* WorldContextObject) override;
virtual void SetReadyToDestroy() override;
protected:
virtual void BeginDestroy() override;
private:
void HandleWorldCleanup(UWorld* World, bool bSessionEnded, bool bCleanupResources);
void UnbindWorldCleanup();
TWeakObjectPtr<UWorld> RegisteredWorld;
FDelegateHandle WorldCleanupHandle;
};
UCLASS(Abstract)
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilCancellableAsyncAction : public UCancellableAsyncAction
{
GENERATED_BODY()
public:
virtual void RegisterWithGameInstance(const UObject* WorldContextObject) override;
virtual void SetReadyToDestroy() override;
protected:
virtual void BeginDestroy() override;
private:
void HandleWorldCleanup(UWorld* World, bool bSessionEnded, bool bCleanupResources);
void UnbindWorldCleanup();
TWeakObjectPtr<UWorld> RegisteredWorld;
FDelegateHandle WorldCleanupHandle;
};

View File

@@ -3,7 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "Tasks/DirectiveUtilAsyncActionBase.h"
#include "UObject/SoftObjectPtr.h"
#include "DirectiveUtilTask_AsyncLoadAsset.generated.h"
@@ -19,7 +19,7 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnAsyncLoadAssetsProgress, int32,
* Asynchronously loads a soft object reference and broadcasts the loaded asset, with a cancel option.
*/
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Async Load Asset"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncLoadAsset : public UBlueprintAsyncActionBase
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncLoadAsset : public UDirectiveUtilAsyncActionBase
{
GENERATED_BODY()
@@ -71,7 +71,7 @@ protected:
* Asynchronously loads a soft class reference and broadcasts the loaded class, with a cancel option.
*/
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Async Load Class"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncLoadClass : public UBlueprintAsyncActionBase
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncLoadClass : public UDirectiveUtilAsyncActionBase
{
GENERATED_BODY()
@@ -124,7 +124,7 @@ protected:
* loaded assets, with progress updates and a cancel option.
*/
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Async Load Assets"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncLoadAssets : public UBlueprintAsyncActionBase
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncLoadAssets : public UDirectiveUtilAsyncActionBase
{
GENERATED_BODY()

View File

@@ -3,7 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "Tasks/DirectiveUtilAsyncActionBase.h"
#include "Engine/EngineTypes.h"
#include "Engine/HitResult.h"
#include "DirectiveUtilTask_AsyncTrace.generated.h"
@@ -28,7 +28,7 @@ enum class EDirectiveUtilTraceShape : uint8
* The trace cannot be cancelled.
*/
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Async Trace"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncTrace : public UBlueprintAsyncActionBase
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_AsyncTrace : public UDirectiveUtilAsyncActionBase
{
GENERATED_BODY()

View File

@@ -3,7 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "Tasks/DirectiveUtilAsyncActionBase.h"
#include "Engine/TimerHandle.h"
#include "DirectiveUtilTask_Delay.generated.h"
@@ -11,10 +11,10 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDelayCompleted);
/**
* DirectiveUtilTask_Delay
* A cancellable delay that can be ended early by calling EndTask.
* A cancellable delay.
*/
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Cancellable Delay"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_Delay : public UBlueprintAsyncActionBase
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_Delay : public UDirectiveUtilCancellableAsyncAction
{
GENERATED_BODY()
@@ -23,10 +23,10 @@ public:
/**
* Starts a cancellable delay.
* When the delay has completed, the Completed delegate is called.
* Call EndTask to cancel the delay before it completes.
* Call Cancel to stop the delay before it completes.
*
* @param WorldContextObject The world context object.
* @param Duration The duration of the delay in seconds.
* @param Duration The duration of the delay in seconds. Non-finite and non-positive values complete on the next timer tick.
*/
UFUNCTION(
BlueprintCallable,
@@ -38,14 +38,13 @@ public:
))
static UDirectiveUtilTask_Delay* CancellableDelay(UObject* WorldContextObject, float Duration);
/**
* Ends the delay early.
*/
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|FlowControl")
UFUNCTION(BlueprintCallable, meta=(DeprecatedFunction, DeprecationMessage="Use Cancel instead."), Category = "Directive Utilities|FlowControl")
void EndTask();
virtual void Activate() override;
virtual void Cancel() override;
virtual bool IsActive() const override;
virtual bool ShouldBroadcastDelegates() const override;
// The delegate called when the delay has completed.
UPROPERTY(BlueprintAssignable)
FOnDelayCompleted Completed;
@@ -55,6 +54,7 @@ protected:
TObjectPtr<UObject> WorldContextObject;
float Duration = 0.0f;
bool bFinished = false;
FTimerHandle TimerHandle;
void OnDelayComplete();

View File

@@ -0,0 +1,121 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "Tasks/DirectiveUtilAsyncActionBase.h"
#include "Engine/TimerHandle.h"
#include "DirectiveUtilTask_Flow.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnDurationUpdated, float, ElapsedTime, float, DeltaTime, float, Alpha);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnDurationCompleted);
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnRepeatIteration, int32, Index, int32, Remaining);
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FOnRepeatCompleted);
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Update for Duration"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_UpdateForDuration : public UDirectiveUtilCancellableAsyncAction
{
GENERATED_BODY()
public:
UFUNCTION(
BlueprintCallable,
meta=(
BlueprintInternalUseOnly = "true",
Category = "Directive Utilities|FlowControl",
WorldContext = "WorldContextObject",
DisplayName = "Update for Duration",
AdvancedDisplay = "UpdateInterval"
))
static UDirectiveUtilTask_UpdateForDuration* UpdateForDuration(
UObject* WorldContextObject,
float Duration,
float UpdateInterval = 0.0f);
virtual void Activate() override;
virtual void Cancel() override;
virtual bool IsActive() const override;
virtual bool ShouldBroadcastDelegates() const override;
UPROPERTY(BlueprintAssignable)
FOnDurationUpdated Updated;
UPROPERTY(BlueprintAssignable)
FOnDurationCompleted Completed;
private:
UPROPERTY()
TObjectPtr<UObject> WorldContextObject;
float Duration = 0.0f;
float UpdateInterval = 0.0f;
float LastElapsedTime = 0.0f;
bool bHasUpdated = false;
bool bFinished = false;
FTimerHandle UpdateTimerHandle;
FTimerHandle CompletionTimerHandle;
void OnUpdate();
void OnComplete();
void BroadcastUpdate(float ElapsedTime, float Alpha);
void ClearTimers();
};
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Repeat with Interval"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_RepeatWithInterval : public UDirectiveUtilCancellableAsyncAction
{
GENERATED_BODY()
public:
/**
* Runs a fixed number of iterations, or forever when Count is -1.
* @param Count - Iteration count. Use -1 to repeat until Cancel. Zero and other negative values complete on the next tick with no iterations.
* @param Interval - Delay between iterations. Non-positive or non-finite values run on consecutive ticks.
* @param InitialDelay - Delay before the first iteration. Non-positive or non-finite values start on the next tick.
*/
UFUNCTION(
BlueprintCallable,
meta=(
BlueprintInternalUseOnly = "true",
Category = "Directive Utilities|FlowControl",
WorldContext = "WorldContextObject",
DisplayName = "Repeat with Interval",
AdvancedDisplay = "InitialDelay"
))
static UDirectiveUtilTask_RepeatWithInterval* RepeatWithInterval(
UObject* WorldContextObject,
int32 Count,
float Interval,
float InitialDelay = 0.0f);
virtual void Activate() override;
virtual void Cancel() override;
virtual bool IsActive() const override;
virtual bool ShouldBroadcastDelegates() const override;
#if WITH_DEV_AUTOMATION_TESTS
void SetNextIndexForTesting(int32 Index) { NextIndex = Index; }
#endif
UPROPERTY(BlueprintAssignable)
FOnRepeatIteration Iteration;
UPROPERTY(BlueprintAssignable)
FOnRepeatCompleted Completed;
private:
UPROPERTY()
TObjectPtr<UObject> WorldContextObject;
int32 Count = 0;
int32 NextIndex = 0;
float Interval = 0.0f;
float InitialDelay = 0.0f;
bool bFinished = false;
FTimerHandle TimerHandle;
void Schedule(float Delay);
void OnIteration();
void Complete();
void ClearTimer();
};

View File

@@ -3,7 +3,7 @@
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "Tasks/DirectiveUtilAsyncActionBase.h"
#include "GameFramework/Controller.h"
#include "DirectiveUtilTask_MoveToLocation.generated.h"
@@ -15,7 +15,7 @@ DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAsyncMoveToActor, bool, bSuccess)
* Asynchronously moves an actor to a location.
*/
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Async Move To Location"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_MoveToLocation : public UBlueprintAsyncActionBase
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_MoveToLocation : public UDirectiveUtilAsyncActionBase
{
GENERATED_BODY()
@@ -27,15 +27,15 @@ public:
* bSuccess is true only when the pawn ends within AcceptanceRadius of Destination; the task also ends
* (with the same distance test) when path-following stops for any reason.
*
* If the controller or pawn is destroyed while moving, the task will automatically end.
* If the controller, pawn, or world becomes unavailable while moving, the task will automatically end.
* If bCheckStuckMovement is enabled and the controller gets stuck while moving, the task will automatically end.
*
* @param WorldContextObject The world context object.
* @param Controller The controller to move.
* @param Destination The vector location to move to.
* @param AcceptanceRadius The radius around the destination location that is considered acceptable. Be sure to set this to a reasonable value as the controller may never reach the exact destination.
* @param AcceptanceRadius The radius around the destination location that is considered acceptable. Negative and non-finite values are treated as zero.
* @param bCheckStuckMovement Check if the controller gets stuck while moving.
* @param StuckThreshold The distance threshold to consider the controller stuck.
* @param StuckThreshold The distance threshold to consider the controller stuck. Negative and non-finite values are treated as zero.
* @param bDebugLineTrace Display a line trace to the destination location for a short duration.
*/
UFUNCTION(
@@ -86,6 +86,8 @@ protected:
FTimerHandle StuckTimerHandle;
TWeakObjectPtr<UWorld> TimerWorld;
bool bHasCompleted = false;
void CheckMoveToLocation();
@@ -100,7 +102,7 @@ protected:
* Asynchronously moves an actor to another actor.
*/
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask, DisplayName="Async Move To Actor"))
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_MoveToActor : public UBlueprintAsyncActionBase
class DIRECTIVEUTILITIESRUNTIME_API UDirectiveUtilTask_MoveToActor : public UDirectiveUtilAsyncActionBase
{
GENERATED_BODY()
@@ -113,15 +115,15 @@ public:
* (with the same distance test) when path-following stops for any reason. The goal's location is re-read
* every poll, so a moving goal is tracked.
*
* If the controller, pawn, or goal actor is destroyed while moving, the task will automatically end.
* If the controller, pawn, goal actor, or world becomes unavailable while moving, the task will automatically end.
* If bCheckStuckMovement is enabled and the controller gets stuck while moving, the task will automatically end.
*
* @param WorldContextObject The world context object.
* @param Controller The controller to move.
* @param Goal The actor to move to.
* @param AcceptanceRadius The radius around the goal actor that is considered acceptable. Be sure to set this to a reasonable value as the controller may never reach the goal's exact location.
* @param AcceptanceRadius The radius around the goal actor that is considered acceptable. Negative and non-finite values are treated as zero.
* @param bCheckStuckMovement Check if the controller gets stuck while moving.
* @param StuckThreshold The distance threshold to consider the controller stuck.
* @param StuckThreshold The distance threshold to consider the controller stuck. Negative and non-finite values are treated as zero.
*/
UFUNCTION(
BlueprintCallable,
@@ -171,6 +173,8 @@ protected:
FTimerHandle StuckTimerHandle;
TWeakObjectPtr<UWorld> TimerWorld;
bool bHasCompleted = false;
void CheckMoveToActor();