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,36 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Types/DirectiveUtilEditorAuditTypes.h"
#include "DirectiveUtilEditorAssetAuditLibrary.generated.h"
UCLASS()
class DIRECTIVEUTILITIESEDITOR_API UDirectiveUtilEditorAssetAuditLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
/** Returns assets with no known Asset Registry referencers. Results are candidates and may still be loaded indirectly. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Asset Audit")
static TArray<FAssetData> FindUnreferencedAssetCandidates(const FDirectiveUtilAssetAuditOptions& Options);
/** Returns Asset Registry dependencies whose packages cannot be found. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Asset Audit")
static TArray<FDirectiveUtilMissingAssetReference> FindMissingAssetReferences(const FDirectiveUtilAssetAuditOptions& Options);
/** Returns dependency cycles between assets in the scanned paths. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Asset Audit")
static TArray<FDirectiveUtilAssetDependencyCycle> FindAssetDependencyCycles(const FDirectiveUtilAssetAuditOptions& Options);
/** Builds a read-only report for assets in the scanned paths. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Asset Audit")
static FDirectiveUtilAssetAuditReport BuildAssetAuditReport(const FDirectiveUtilAssetAuditOptions& Options);
/** Converts an asset audit report to CSV text. */
UFUNCTION(BlueprintPure, Category = "Directive Utilities|Editor|Asset Audit")
static FString AssetAuditReportToCsv(const FDirectiveUtilAssetAuditReport& Report);
};

View File

@@ -2,6 +2,7 @@
#pragma once
#include "AssetRegistry/AssetData.h"
#include "CoreMinimal.h"
#include "EditorAssetLibrary.h"
#include "Types/DirectiveUtilEditorAssetTypes.h"
@@ -44,7 +45,8 @@ public:
/**
* Fixes up (and deletes) object redirectors found under the given directories, without loading every asset.
* Equivalent to the Content Browser's "Fix Up Redirectors in Folder", but scriptable and headless-friendly.
* Equivalent to the Content Browser's "Fix Up Redirectors in Folder". Unreal shows a completion dialog,
* so this returns Failure in unattended sessions instead of blocking the process.
* @param DirectoryPaths Directories to scan for redirectors. If empty, the entire registry is scanned.
* @param OutRedirectorsProcessed [out] The number of redirectors submitted for fix-up (the engine does not report per-redirector success).
* @return Success if the operation ran (even if nothing needed fixing), Failure otherwise (e.g. a fixup is already in progress).

View File

@@ -0,0 +1,49 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "AssetRegistry/AssetData.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Types/DirectiveUtilEditorBlueprintTypes.h"
#include "DirectiveUtilEditorBlueprintLibrary.generated.h"
class UBlueprint;
UCLASS()
class DIRECTIVEUTILITIESEDITOR_API UDirectiveUtilEditorBlueprintLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintPure, Category = "Directive Utilities|Editor|Blueprint Inspection")
static EDirectiveUtilBlueprintCompileStatus GetBlueprintCompileStatus(const UBlueprint* Blueprint);
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Blueprint Inspection")
static TArray<FAssetData> FindBlueprintsByCompileStatus(
EDirectiveUtilBlueprintCompileStatus CompileStatus,
const FDirectiveUtilBlueprintSearchOptions& Options);
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Blueprint Inspection")
static TArray<FAssetData> FindBlueprintsByParentClass(
UClass* ParentClass,
const FDirectiveUtilBlueprintSearchOptions& Options,
bool bIncludeDescendants = true);
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Blueprint Inspection")
static TArray<FAssetData> FindBlueprintsImplementingInterface(
UClass* InterfaceClass,
const FDirectiveUtilBlueprintSearchOptions& Options);
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Blueprint Inspection")
static TArray<FAssetData> FindBlueprintsContainingComponentClass(
UClass* ComponentClass,
const FDirectiveUtilBlueprintSearchOptions& Options,
bool bIncludeDerivedComponents = true);
UFUNCTION(BlueprintPure, Category = "Directive Utilities|Editor|Blueprint Inspection")
static TArray<FName> GetUnusedBlueprintVariables(
UBlueprint* Blueprint,
bool bIncludeExternallyAccessibleVariables = false);
};

View File

@@ -0,0 +1,25 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Types/DirectiveUtilEditorTaskTypes.h"
#include "DirectiveUtilEditorTaskLibrary.generated.h"
class UDirectiveUtilEditorSlowTask;
UCLASS()
class DIRECTIVEUTILITIESEDITOR_API UDirectiveUtilEditorTaskLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
/** Starts a modal editor progress task. TotalWork must be greater than zero, and only one task can be active. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Task")
static UDirectiveUtilEditorSlowTask* StartEditorSlowTask(float TotalWork, const FText& Description, bool bCanCancel = false);
/** Displays a fire-and-forget editor notification. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Notification")
static bool ShowEditorNotification(const FText& Message, EDirectiveUtilEditorNotificationState State = EDirectiveUtilEditorNotificationState::Neutral, float ExpireDuration = 3.0f);
};

View File

@@ -11,7 +11,7 @@
class UCapsuleComponent;
class UBoxComponent;
class USphereComponent;
class UStaticMeshActor;
class AStaticMeshActor;
/**
* DirectiveUtilEditorActorSubsystem
@@ -44,6 +44,30 @@ public:
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor")
TArray<UClass*> GetAllLevelClasses();
/** Aligns actor bounds to the combined minimum, center, or maximum on one axis. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Actor Layout")
static FDirectiveUtilActorOperationResult AlignActors(
const TArray<AActor*>& Actors,
EDirectiveUtilActorLayoutAxis Axis,
EDirectiveUtilActorAlignment Alignment);
/** Distributes actors between the outer actors using equal center spacing or equal bounds gaps. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Actor Layout")
static FDirectiveUtilActorOperationResult DistributeActors(
const TArray<AActor*>& Actors,
EDirectiveUtilActorLayoutAxis Axis,
EDirectiveUtilActorDistribution Distribution);
/** Traces from each actor and places its pivot or directional bounds on the hit surface. */
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Actor Layout", meta = (AdvancedDisplay = "bAlignToNormal"))
static FDirectiveUtilActorOperationResult SnapActorsToSurface(
const TArray<AActor*>& Actors,
FVector TraceDirection,
float MaximumDistance,
TEnumAsByte<ECollisionChannel> TraceChannel = ECC_Visibility,
EDirectiveUtilSurfacePlacement Placement = EDirectiveUtilSurfacePlacement::Bounds,
bool bAlignToNormal = false);
//-----------------------------
// Filters
//-----------------------------
@@ -679,7 +703,7 @@ public:
* Returns a list of invalid actors.
* @param FoundActors The list of actors that were found.
*/
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Select", meta=(AdvancedDisplay=1))
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Select", meta=(DeprecatedFunction, DeprecationMessage="Actor enumeration excludes invalid actors. This node always returns an empty array."))
void GetInvalidActors(TArray<AActor*>& FoundActors);
//-----------------------------

View File

@@ -0,0 +1,33 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "DirectiveUtilEditorSlowTask.generated.h"
struct FScopedSlowTask;
UCLASS(BlueprintType)
class DIRECTIVEUTILITIESEDITOR_API UDirectiveUtilEditorSlowTask : public UObject
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Task")
bool Advance(float Work, const FText& Message);
UFUNCTION(BlueprintPure, Category = "Directive Utilities|Editor|Task")
bool IsCancelRequested() const;
UFUNCTION(BlueprintPure, Category = "Directive Utilities|Editor|Task")
bool IsActive() const;
UFUNCTION(BlueprintCallable, Category = "Directive Utilities|Editor|Task")
void Finish();
void Initialize(float TotalWork, const FText& Description, bool bCanCancel, bool bShowDialog);
static void FinishActiveTask();
private:
FScopedSlowTask* SlowTask = nullptr;
};

View File

@@ -0,0 +1,112 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "AssetRegistry/AssetData.h"
#include "DirectiveUtilEditorAuditTypes.generated.h"
UENUM(BlueprintType)
enum class EDirectiveUtilAssetDependencyType : uint8
{
HardPackage UMETA(DisplayName = "Hard Package"),
SoftPackage UMETA(DisplayName = "Soft Package"),
SearchableName UMETA(DisplayName = "Searchable Name"),
DirectManagement UMETA(DisplayName = "Direct Management"),
IndirectManagement UMETA(DisplayName = "Indirect Management"),
};
USTRUCT(BlueprintType)
struct FDirectiveUtilAssetAuditOptions
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Directive Utilities|Asset Audit")
TArray<FName> PackagePaths;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Directive Utilities|Asset Audit")
TArray<FName> ExcludedPackagePaths;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Directive Utilities|Asset Audit")
bool bUseDefaultPathExclusions = true;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Directive Utilities|Asset Audit")
bool bIncludePrimaryAssets = false;
FDirectiveUtilAssetAuditOptions()
{
PackagePaths.Add(TEXT("/Game"));
}
};
USTRUCT(BlueprintType)
struct FDirectiveUtilMissingAssetReference
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
FAssetData ReferencingAsset;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
FName MissingPackage;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
EDirectiveUtilAssetDependencyType DependencyType = EDirectiveUtilAssetDependencyType::SoftPackage;
};
USTRUCT(BlueprintType)
struct FDirectiveUtilAssetDependencyCycle
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
TArray<FName> Packages;
};
USTRUCT(BlueprintType)
struct FDirectiveUtilAssetAuditEntry
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
FAssetData Asset;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
FName PackageName;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
FName PackagePath;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
FString AssetClass;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
int64 DiskSize = 0;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
int32 DependencyCount = 0;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
int32 ReferencerCount = 0;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
bool bPrimaryAsset = false;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
TArray<FString> Findings;
};
USTRUCT(BlueprintType)
struct FDirectiveUtilAssetAuditReport
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
TArray<FDirectiveUtilAssetAuditEntry> Assets;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
TArray<FDirectiveUtilMissingAssetReference> MissingReferences;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Asset Audit")
TArray<FDirectiveUtilAssetDependencyCycle> DependencyCycles;
};

View File

@@ -0,0 +1,34 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "CoreMinimal.h"
#include "DirectiveUtilEditorBlueprintTypes.generated.h"
UENUM(BlueprintType)
enum class EDirectiveUtilBlueprintCompileStatus : uint8
{
Unknown,
Dirty,
Error,
UpToDate UMETA(DisplayName = "Up To Date"),
BeingCreated UMETA(DisplayName = "Being Created"),
UpToDateWithWarnings UMETA(DisplayName = "Up To Date With Warnings"),
};
USTRUCT(BlueprintType)
struct FDirectiveUtilBlueprintSearchOptions
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Directive Utilities|Blueprint Inspection")
TArray<FName> PackagePaths;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Directive Utilities|Blueprint Inspection")
TArray<FName> ExcludedPackagePaths;
FDirectiveUtilBlueprintSearchOptions()
{
PackagePaths.Add(TEXT("/Game"));
}
};

View File

@@ -0,0 +1,14 @@
// Copyright (c) 2026 Unreal Directive. Licensed under the MIT License.
#pragma once
#include "DirectiveUtilEditorTaskTypes.generated.h"
UENUM(BlueprintType)
enum class EDirectiveUtilEditorNotificationState : uint8
{
Neutral,
Success,
Warning,
Failure
};

View File

@@ -3,6 +3,51 @@
#pragma once
#include "CoreMinimal.h"
#include "DirectiveUtilEditorTypes.generated.h"
class AActor;
UENUM(BlueprintType)
enum class EDirectiveUtilActorLayoutAxis : uint8
{
X,
Y,
Z,
};
UENUM(BlueprintType)
enum class EDirectiveUtilActorAlignment : uint8
{
Minimum,
Center,
Maximum,
};
UENUM(BlueprintType)
enum class EDirectiveUtilActorDistribution : uint8
{
Centers,
BoundsGaps UMETA(DisplayName = "Bounds Gaps"),
};
UENUM(BlueprintType)
enum class EDirectiveUtilSurfacePlacement : uint8
{
Pivot,
Bounds,
};
USTRUCT(BlueprintType)
struct FDirectiveUtilActorOperationResult
{
GENERATED_BODY()
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Actor Layout")
TArray<TObjectPtr<AActor>> ChangedActors;
UPROPERTY(BlueprintReadOnly, Category = "Directive Utilities|Actor Layout")
TArray<TObjectPtr<AActor>> SkippedActors;
};
/**
* EDirectiveUtilSelectionMethod