工作时动画需要复用一些曲线用于morphtarget,遂做了一个对动画的曲线进行导入导出的工具
// Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
public class MyProjectEditor : ModuleRules
{
public MyProjectEditor(ReadOnlyTargetRules Target) : base(Target)
{
PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
PublicDependencyModuleNames.AddRange(new string[] {
"Core", "CoreUObject", "Engine", "InputCore", "MyProject"});
PrivateDependencyModuleNames.AddRange(new string[]
{
"AnimationModifiers", "AssetRegistry", "UnrealEd"
});
}
}
#include "AnimationModifiers/Public/AnimationBlueprintLibrary.h"
#include "AssetRegistry/AssetRegistryModule.h"
#include "Factories/CurveFactory.h"
#include "EditorLevelUtils.h"
bool UFTBlueprintToolLibrary::ExportCurve(UAnimSequence* Seq, FName CurveName)
{
if (Seq == nullptr) return false;
TArray<FName> CurveNames;
UAnimationBlueprintLibrary::GetAnimationCurveNames(Seq, ERawCurveTrackTypes::RCT_Float, CurveNames);
if (CurveNames.Find(CurveName) != -1)
{
//UCurveFloat* NewCurveResource = NewObject<UCurveFloat>();
TArray<float> Times;
TArray<float> Values;
UAnimationBlueprintLibrary::GetFloatKeys(Seq, CurveName, Times, Values);
if (Times.Num() == Values.Num())
{
FAssetRegistryModule* const AssetRegistryModule = FModuleManager::Get().GetModulePtr<FAssetRegistryModule>("AssetRegistry");
IAssetRegistry& AssetRegistry = AssetRegistryModule->Get();
const auto CurveFactory = NewObject<UCurveFactory>();
CurveFactory->CurveClass = UCurveFloat::StaticClass();
FString CurveResName = "CF_" + CurveName.ToString();
//remove illegal name
CurveResName = CurveResName.Replace(TEXT(" "), TEXT(""));
const FString PackageName = "/Game/" + CurveResName;
UPackage* Package = CreatePackage(*PackageName);
UObject* NewResource = CurveFactory->FactoryCreateNew(UCurveFactory::StaticClass(), Package, *CurveResName, RF_Standalone | RF_Public, nullptr, GWarn);
//UAssetRegistryHelpers::CreateAssetData(NewCurveResource);
//UAssetRegistryHelpers::GetAssetRegistry()->AssetCreated(NewCurveResource);
auto* NewCurveResource = Cast<UCurveFloat>(NewResource);
for (int i = 0; i < Times.Num(); ++i)
{
NewCurveResource->FloatCurve.AddKey(Times[i], Values[i]);
}
AssetRegistry.AssetCreated(NewCurveResource);
NewCurveResource->MarkPackageDirty();
Package->SetDirtyFlag(true);
NewCurveResource->PostEditChange();
NewCurveResource->AddToRoot();
return true;
}
}
return false;
}
//MapRange true:Map Curve Length to Animation Length \false: truncation
bool UFTBlueprintToolLibrary::ApplyCurve(UCurveFloat* Curve, UAnimSequence* Seq, FName CurveName, bool MapRange)
{
if (Curve == nullptr || Seq == nullptr)
{
return false;
}
UAnimationBlueprintLibrary::RemoveCurve(Seq, CurveName);
UAnimationBlueprintLibrary::AddCurve(Seq, CurveName);
TArray<float> Times;
TArray<float> Values;
float Range = 0;
if (MapRange)
{
float MinTime, MaxTime = 0;
Curve->FloatCurve.GetTimeRange(MinTime, MaxTime);
Range = MaxTime - MinTime;
}
for (int i = 0; i < Curve->FloatCurve.Keys.Num(); ++i)
{
float TempTime = Curve->FloatCurve.GetConstRefOfKeys()[i].Time;
if (MapRange)
{
TempTime = Seq->SequenceLength / Range * TempTime;
}
Times.Add(TempTime);
Values.Add(Curve->FloatCurve.GetConstRefOfKeys()[i].Value);
}
UAnimationBlueprintLibrary::AddFloatCurveKeys(Seq, CurveName, std::move(Times), std::move(Values));
Seq->MarkPackageDirty();
//Package->SetDirtyFlag(true);
return true;
}