#pragma once #include "CoreMinimal.h" #include "WingServer.h" #include "WingHandler.h" #include "WingFetcher.h" #include "WingUtils.h" #include "WingPackageMaker.h" #include "Animation/AnimBlueprint.h" #include "Animation/AnimBlueprintGeneratedClass.h" #include "Animation/AnimInstance.h" #include "Animation/Skeleton.h" #include "Kismet2/KismetEditorUtilities.h" #include "AnimBlueprint_Create.generated.h" // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- // --------------------------------------------------------------------------- UCLASS() class UWing_AnimBlueprint_Create : public UObject, public IWingHandler { GENERATED_BODY() public: UPROPERTY(meta=(Description="Full asset path for the new Animation Blueprint (e.g. '/Game/AnimBP/ABP_Character')")) FString AssetPath; UPROPERTY(meta=(Description="Skeleton asset package path")) FString Skeleton; UPROPERTY(meta=(Optional, Description="Parent class name (default: AnimInstance)")) FString ParentClass; virtual FString GetDescription() const override { return TEXT("Create a new Animation Blueprint asset with a specified skeleton."); } virtual void Handle() override { WingPackageMaker Maker(AssetPath); if (!Maker.Ok()) return; // Resolve skeleton WingFetcher SkeletonFetcher; USkeleton* SkeletonObj = SkeletonFetcher.Asset(Skeleton).Cast(); if (!SkeletonObj) return; // Resolve parent class (default: UAnimInstance) UClass* ParentClassObj = UAnimInstance::StaticClass(); if (!ParentClass.IsEmpty() && !ParentClass.Equals(TEXT("AnimInstance"), ESearchCase::IgnoreCase)) { UClass* Found = nullptr; for (TObjectIterator It; It; ++It) { if (It->IsChildOf(UAnimInstance::StaticClass()) && WingUtils::Identifies(ParentClass, *It)) { Found = *It; break; } } if (!Found) { UWingServer::Printf(TEXT("ERROR: Parent class '%s' not found (must derive from AnimInstance)\n"), *ParentClass); return; } ParentClassObj = Found; } // Create the package and Animation Blueprint if (!Maker.Make()) return; UAnimBlueprint* NewAnimBP = CastChecked( FKismetEditorUtilities::CreateBlueprint( ParentClassObj, Maker.Package(), FName(*Maker.Name()), BPTYPE_Normal, UAnimBlueprint::StaticClass(), UAnimBlueprintGeneratedClass::StaticClass() )); if (!NewAnimBP) { UWingServer::Print(TEXT("ERROR: FKismetEditorUtilities::CreateBlueprint returned null\n")); return; } // Set target skeleton NewAnimBP->TargetSkeleton = SkeletonObj; // Compile FKismetEditorUtilities::CompileBlueprint(NewAnimBP); UWingServer::Printf(TEXT("Created: %s\n"), *AssetPath); UWingServer::Printf(TEXT("ParentClass: %s\n"), *WingUtils::FormatName(ParentClassObj)); TArray Graphs = WingUtils::AllGraphs(NewAnimBP); for (UEdGraph* Graph : Graphs) { UWingServer::Printf(TEXT("Graph: %s\n"), *WingUtils::FormatName(Graph)); } } };