Big refactor of ScriptedAnimations, moved into their own source file, lots of reorganization.
This commit is contained in:
@@ -12,10 +12,11 @@
|
|||||||
//
|
//
|
||||||
// An single animation step.
|
// An single animation step.
|
||||||
//
|
//
|
||||||
// The body consists of a sequence of FlxAnimationField
|
// This struct contains an entire animation step. The
|
||||||
// records. The body is encoded, to read the
|
// key-value pairs are stored in an encoded form, which is not
|
||||||
// FlxAnimationField records you need an
|
// directly accessible to blueprints. To read these key-value
|
||||||
// FlxAnimationStepDecoder.
|
// pairs, blueprints will need to use UnpackAnimationStep or
|
||||||
|
// AnimationStepGetXXX.
|
||||||
//
|
//
|
||||||
////////////////////////////////////////////////
|
////////////////////////////////////////////////
|
||||||
|
|
||||||
@@ -27,9 +28,15 @@ public:
|
|||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
bool Finished;
|
bool Finished;
|
||||||
|
|
||||||
UPROPERTY()
|
// The hash of the animation step, a 63-bit unique identifier.
|
||||||
|
//
|
||||||
|
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
|
||||||
int64 Hash;
|
int64 Hash;
|
||||||
|
|
||||||
|
// The Body contains all the key-value pairs in an encoded form. To
|
||||||
|
// obtain these in a useful form, you will need to use
|
||||||
|
// UnpackAnimationStep or AnimationStepGetXXX.
|
||||||
|
//
|
||||||
UPROPERTY()
|
UPROPERTY()
|
||||||
TArray<uint8> Body;
|
TArray<uint8> Body;
|
||||||
|
|
||||||
|
|||||||
177
Source/Integration/ScriptedAnimation.cpp
Normal file
177
Source/Integration/ScriptedAnimation.cpp
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#include "ScriptedAnimation.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Routines to calculate the current state of an FlxScriptedAnimation.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::CalculateFade(double Offset, double Fade)
|
||||||
|
{
|
||||||
|
if (Offset < 0.0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
if (Fade > 0.001)
|
||||||
|
{
|
||||||
|
return FMath::Min(Offset / Fade, 1.0);
|
||||||
|
}
|
||||||
|
return 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::UnclampedElapsedTime(double CurrentTime) const
|
||||||
|
{
|
||||||
|
return CurrentTime - StartTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::UnclampedTimeLeft(double CurrentTime) const
|
||||||
|
{
|
||||||
|
return EndTime - CurrentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::ClampedElapsedTime(double CurrentTime) const
|
||||||
|
{
|
||||||
|
return FMath::Max(0.0, CurrentTime - StartTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::ClampedTimeLeft(double CurrentTime) const
|
||||||
|
{
|
||||||
|
return FMath::Max(0.0, EndTime - CurrentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::CalcFadeInAlpha(double CurrentTime) const
|
||||||
|
{
|
||||||
|
return CalculateFade(UnclampedElapsedTime(CurrentTime), FadeInDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::CalcFadeOutAlpha(double CurrentTime) const
|
||||||
|
{
|
||||||
|
return CalculateFade(UnclampedTimeLeft(CurrentTime), FadeOutDuration);
|
||||||
|
}
|
||||||
|
|
||||||
|
double FlxScriptedAnimation::CalcFadeInOutAlpha(double CurrentTime) const
|
||||||
|
{
|
||||||
|
return FMath::Min(CalcFadeInAlpha(CurrentTime), CalcFadeOutAlpha(CurrentTime));
|
||||||
|
}
|
||||||
|
|
||||||
|
void FlxScriptedAnimation::InitiateFadeOut(double CurrentTime, double AllowedFade)
|
||||||
|
{
|
||||||
|
// We only need to truncate if we aren't already fading out,
|
||||||
|
// or if the in-progress fadeout isn't sufficiently fast.
|
||||||
|
//
|
||||||
|
double FadeOutAlpha = CalcFadeOutAlpha(CurrentTime);
|
||||||
|
if ((FadeOutAlpha >= 1.0) || (FadeOutDuration > AllowedFade))
|
||||||
|
{
|
||||||
|
double CurrentAlpha = FMath::Min(CalcFadeInAlpha(CurrentTime), FadeOutAlpha);
|
||||||
|
double NewFadeOutDuration = FMath::Min(AllowedFade, FadeOutDuration);
|
||||||
|
double NewTimeLeft = NewFadeOutDuration * CurrentAlpha;
|
||||||
|
EndTime = CurrentTime + NewTimeLeft;
|
||||||
|
FadeOutDuration = NewFadeOutDuration;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UlxScriptedAnimations::Keep(int n)
|
||||||
|
{
|
||||||
|
if (n < 0) n = 0;
|
||||||
|
if (Animations.Num() > n)
|
||||||
|
{
|
||||||
|
Animations.SetNum(n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UlxScriptedAnimations::AddAnimation(
|
||||||
|
UObject* WorldContextObject, UAnimSequenceBase* Sequence, double FadeInTime, double FadeOutTime, int64 AqHash)
|
||||||
|
{
|
||||||
|
check(KeepCount >= 1);
|
||||||
|
FlxScriptedAnimation Result;
|
||||||
|
|
||||||
|
// Get World Time
|
||||||
|
UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
|
||||||
|
double WorldTime = World ? World->GetTimeSeconds() : 0.0;
|
||||||
|
|
||||||
|
// Get the animation Length.
|
||||||
|
double Length = (Sequence ? static_cast<double>(Sequence->GetPlayLength()) : 0.0);
|
||||||
|
|
||||||
|
// Fill the static setup fields
|
||||||
|
Result.Sequence = Sequence;
|
||||||
|
Result.AqHash = AqHash;
|
||||||
|
Result.FadeInDuration = FadeInTime;
|
||||||
|
Result.FadeOutDuration = FadeOutTime;
|
||||||
|
Result.StartTime = WorldTime;
|
||||||
|
Result.EndTime = WorldTime + Length;
|
||||||
|
|
||||||
|
Keep(KeepCount - 1);
|
||||||
|
Animations.Insert(Result, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UlxScriptedAnimations::FadeGarbage(TArray<int32> Hashes, double CurrentTime)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Animations.Num(); i++)
|
||||||
|
{
|
||||||
|
FlxScriptedAnimation &Anim = Animations[i];
|
||||||
|
if ((Anim.AqHash != 0) && (!Hashes.Contains(Anim.AqHash)))
|
||||||
|
{
|
||||||
|
Anim.InitiateFadeOut(CurrentTime, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UlxScriptedAnimationLibrary::ScriptedAnimationEvaluatorData(const UlxScriptedAnimations *Animations, double CurrentTime,
|
||||||
|
UAnimSequenceBase *&Sequence0, float &ExplicitTime0,
|
||||||
|
UAnimSequenceBase *&Sequence1, float &ExplicitTime1,
|
||||||
|
UAnimSequenceBase *&Sequence2, float &ExplicitTime2,
|
||||||
|
float &BaseAlpha, float &Sequence0Alpha, float &Sequence1Alpha, float &Sequence2Alpha)
|
||||||
|
{
|
||||||
|
Sequence0 = nullptr;
|
||||||
|
Sequence1 = nullptr;
|
||||||
|
Sequence2 = nullptr;
|
||||||
|
ExplicitTime0 = 0.0;
|
||||||
|
ExplicitTime1 = 0.0;
|
||||||
|
ExplicitTime2 = 0.0;
|
||||||
|
BaseAlpha = 0.0;
|
||||||
|
Sequence0Alpha = 0.0;
|
||||||
|
Sequence1Alpha = 0.0;
|
||||||
|
Sequence2Alpha = 0.0;
|
||||||
|
|
||||||
|
if (Animations != nullptr)
|
||||||
|
{
|
||||||
|
const TArray<FlxScriptedAnimation> &Anims = Animations->GetAnimations();
|
||||||
|
if (Anims.Num() > 0)
|
||||||
|
{
|
||||||
|
const FlxScriptedAnimation &Anim = Anims[0];
|
||||||
|
Sequence0 = Anim.Sequence;
|
||||||
|
ExplicitTime0 = Anim.ClampedElapsedTime(CurrentTime);
|
||||||
|
Sequence0Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
|
||||||
|
}
|
||||||
|
if (Anims.Num() > 1)
|
||||||
|
{
|
||||||
|
const FlxScriptedAnimation &Anim = Anims[1];
|
||||||
|
Sequence1 = Anim.Sequence;
|
||||||
|
ExplicitTime1 = Anim.ClampedElapsedTime(CurrentTime);
|
||||||
|
Sequence1Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
|
||||||
|
}
|
||||||
|
if (Anims.Num() > 2)
|
||||||
|
{
|
||||||
|
const FlxScriptedAnimation &Anim = Anims[2];
|
||||||
|
Sequence2 = Anim.Sequence;
|
||||||
|
ExplicitTime2 = Anim.ClampedElapsedTime(CurrentTime);
|
||||||
|
Sequence2Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
double AlphaTotal = Sequence0Alpha + Sequence1Alpha + Sequence2Alpha;
|
||||||
|
if (AlphaTotal > 1.0)
|
||||||
|
{
|
||||||
|
double Scale = 1.0 / AlphaTotal;
|
||||||
|
Sequence0Alpha *= Scale;
|
||||||
|
Sequence1Alpha *= Scale;
|
||||||
|
Sequence2Alpha *= Scale;
|
||||||
|
BaseAlpha = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
BaseAlpha = 1.0 - AlphaTotal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
174
Source/Integration/ScriptedAnimation.h
Normal file
174
Source/Integration/ScriptedAnimation.h
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
#include "CoreMinimal.h"
|
||||||
|
// #include "Kismet/KismetSystemLibrary.h"
|
||||||
|
// #include "CommonTypes.h"
|
||||||
|
// #include "Kismet/BlueprintFunctionLibrary.h"
|
||||||
|
|
||||||
|
#include "ScriptedAnimation.generated.h"
|
||||||
|
|
||||||
|
class UEnhancedInputLocalPlayerSubsystem;
|
||||||
|
class UAnimSequenceBase;
|
||||||
|
|
||||||
|
|
||||||
|
USTRUCT(BlueprintType)
|
||||||
|
struct INTEGRATION_API FlxScriptedAnimation
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||||
|
UAnimSequenceBase *Sequence = nullptr;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
||||||
|
int64 AqHash = 0;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
||||||
|
double FadeInDuration = 0.0;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
||||||
|
double FadeOutDuration = 0.0;
|
||||||
|
|
||||||
|
// StartTime and EndTime.
|
||||||
|
//
|
||||||
|
// StartTime is the world time when the animation was actually started.
|
||||||
|
// That is immutable once the animation is created. However, EndTime is
|
||||||
|
// mutable: initially, it is set to StartTime + Animation.Length. But
|
||||||
|
// script requests that the animation be truncated, the EndTime
|
||||||
|
// may be reduced to implement the truncation.
|
||||||
|
//
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
||||||
|
double StartTime = 0.0;
|
||||||
|
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
||||||
|
double EndTime = 0.0;
|
||||||
|
|
||||||
|
// Calculate the progress of a fade.
|
||||||
|
//
|
||||||
|
static double CalculateFade(double Offset, double Fade);
|
||||||
|
|
||||||
|
// Calculate Elapsed Time (unclamped)
|
||||||
|
//
|
||||||
|
// If current time is before the animation's start time, then
|
||||||
|
// elapsed time will be negative.
|
||||||
|
//
|
||||||
|
double UnclampedElapsedTime(double CurrentTime) const;
|
||||||
|
|
||||||
|
// Calculate Time Left (unclamped)
|
||||||
|
//
|
||||||
|
// If current time is after the animation's end time, then
|
||||||
|
// time left will be negative.
|
||||||
|
//
|
||||||
|
double UnclampedTimeLeft(double CurrentTime) const;
|
||||||
|
|
||||||
|
// Calculate Elapsed Time (clamped)
|
||||||
|
//
|
||||||
|
// If current time is before the animation's start time, then
|
||||||
|
// elapsed time will be zero.
|
||||||
|
//
|
||||||
|
double ClampedElapsedTime(double CurrentTime) const;
|
||||||
|
|
||||||
|
// Calculate Time Left (clamped)
|
||||||
|
//
|
||||||
|
// If current time is after the animation's end time, then
|
||||||
|
// time left will be zero.
|
||||||
|
//
|
||||||
|
double ClampedTimeLeft(double CurrentTime) const;
|
||||||
|
|
||||||
|
// Calculate the progress of the fadein.
|
||||||
|
//
|
||||||
|
double CalcFadeInAlpha(double CurrentTime) const;
|
||||||
|
|
||||||
|
// Calculate the progress of the fadeout.
|
||||||
|
//
|
||||||
|
double CalcFadeOutAlpha(double CurrentTime) const;
|
||||||
|
|
||||||
|
// Calculate the combined alpha of the fade-in-out.
|
||||||
|
//
|
||||||
|
double CalcFadeInOutAlpha(double CurrentTime) const;
|
||||||
|
|
||||||
|
// Cause an animation to start fading right away.
|
||||||
|
//
|
||||||
|
// Sets up the animation to start fading immediately, by adjusting
|
||||||
|
// the animation's EndTime. If the FadeOut time of the animation
|
||||||
|
// is longer than the allowed fade, that will be reduced.
|
||||||
|
// If the animation was already in the process of fading in
|
||||||
|
// or fading out, then that will be taken into account.
|
||||||
|
//
|
||||||
|
// If you want to chop an animation off abruptly, without any fade,
|
||||||
|
// simply set AllowedFade to 0.0.
|
||||||
|
//
|
||||||
|
void InitiateFadeOut(double CurrentTime, double AllowedFade);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
UCLASS(BlueprintType)
|
||||||
|
class INTEGRATION_API UlxScriptedAnimations : public UObject
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
private:
|
||||||
|
UPROPERTY()
|
||||||
|
int KeepCount = 3;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
TArray<FlxScriptedAnimation> Animations;
|
||||||
|
|
||||||
|
// If the number of elements in the array exceeds the count, discard.
|
||||||
|
//
|
||||||
|
void Keep(int n);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Allow read-only access anywhere.
|
||||||
|
//
|
||||||
|
const TArray<FlxScriptedAnimation> &GetAnimations() const { return Animations; }
|
||||||
|
|
||||||
|
// Add a scripted animation.
|
||||||
|
//
|
||||||
|
// The step is inserted at the front of the array: the first animation
|
||||||
|
// in the array is always the most recent. All other steps are shifted
|
||||||
|
// back. If the array size exceeds the KeepCount, it is truncated.
|
||||||
|
//
|
||||||
|
// The Aq Hash parameter can be used to associate a scripted animation
|
||||||
|
// with a step in the animation queue. This makes it feasible to garbage
|
||||||
|
// collect the scripted animation if the animation queue step disappears.
|
||||||
|
//
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Luprex|Scripted Animations", meta=(WorldContext = "WorldContextObject"))
|
||||||
|
void AddAnimation(
|
||||||
|
UObject *WorldContextObject, UAnimSequenceBase* Sequence, double FadeInTime = 0.2, double FadeOutTime = 0.2, int64 AqHash=0);
|
||||||
|
|
||||||
|
// Fade animations whose corresponding animation queue step is dead.
|
||||||
|
//
|
||||||
|
// Sometimes, predictive reexecution causes an animation step to
|
||||||
|
// vanish from the animation queue. When that happens, it is usually
|
||||||
|
// desirable to terminate any scripted animations that were launched
|
||||||
|
// by that animation step. You don't want to cut them off abruptly,
|
||||||
|
// you want to fade them out. This function causes all animations that
|
||||||
|
// are owned by a dead animation step to begin fading.
|
||||||
|
//
|
||||||
|
UFUNCTION(BlueprintCallable, Category = "Luprex|Scripted Animations", meta=(WorldContext = "WorldContextObject"))
|
||||||
|
void FadeGarbage(TArray<int32> Hashes, double CurrentTime);
|
||||||
|
};
|
||||||
|
|
||||||
|
UCLASS()
|
||||||
|
class INTEGRATION_API UlxScriptedAnimationLibrary : public UBlueprintFunctionLibrary
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Get the data to drive Sequence Evaluators and Multi Blend
|
||||||
|
//
|
||||||
|
// To apply scripted animations in an Anim Graph, you will need
|
||||||
|
// three sequence evaluators and a multi-blend node. This
|
||||||
|
// function outputs the input parameters for all of those nodes.
|
||||||
|
//
|
||||||
|
UFUNCTION(BlueprintPure, Category = "Luprex|Scripted Animations", meta=(BlueprintThreadSafe))
|
||||||
|
static void ScriptedAnimationEvaluatorData(const UlxScriptedAnimations *Animations, double CurrentTime,
|
||||||
|
UAnimSequenceBase *&Sequence0, float &ExplicitTime0,
|
||||||
|
UAnimSequenceBase *&Sequence1, float &ExplicitTime1,
|
||||||
|
UAnimSequenceBase *&Sequence2, float &ExplicitTime2,
|
||||||
|
float &BaseAlpha, float &Sequence0Alpha, float &Sequence1Alpha, float &Sequence2Alpha);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
@@ -213,121 +213,6 @@ void UlxUtilityLibrary::GetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UlxScriptedAnimations::Keep(int n)
|
|
||||||
{
|
|
||||||
if (n < 0) n = 0;
|
|
||||||
if (Animations.Num() > n)
|
|
||||||
{
|
|
||||||
Animations.SetNum(n);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UlxScriptedAnimations::AddAnimation(
|
|
||||||
UObject* WorldContextObject, UAnimSequenceBase* Sequence, double FadeInTime, double FadeOutTime)
|
|
||||||
{
|
|
||||||
check(KeepCount >= 1);
|
|
||||||
FlxScriptedAnimation Result;
|
|
||||||
|
|
||||||
// Get World Time
|
|
||||||
UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
|
|
||||||
double WorldTime = World ? World->GetTimeSeconds() : 0.0;
|
|
||||||
|
|
||||||
// Fill the static setup fields
|
|
||||||
Result.Sequence = Sequence;
|
|
||||||
Result.FadeIn = FadeInTime;
|
|
||||||
Result.FadeOut = FadeOutTime;
|
|
||||||
Result.StartTime = WorldTime;
|
|
||||||
Result.AdjustedLength = (Result.Sequence ? static_cast<double>(Result.Sequence->GetPlayLength()) : 0.0);
|
|
||||||
|
|
||||||
Keep(KeepCount - 1);
|
|
||||||
Animations.Insert(Result, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UlxScriptedAnimations::FadeOutAll(UObject *WorldContextObject)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
FlxScriptedAnimationProgress UlxUtilityLibrary::ScriptedAnimationProgress(const FlxScriptedAnimation &Animation, double CurrentTime)
|
|
||||||
{
|
|
||||||
FlxScriptedAnimationProgress Progress(Animation);
|
|
||||||
|
|
||||||
// Store the world time of the last update.
|
|
||||||
Progress.UpdateTime = CurrentTime;
|
|
||||||
|
|
||||||
// Compute time relationships
|
|
||||||
Progress.EndTime = Animation.StartTime + Progress.AdjustedLength;
|
|
||||||
Progress.ElapsedTime = FMath::Max(0.0, Progress.UpdateTime - Progress.StartTime);
|
|
||||||
Progress.TimeLeft = FMath::Max(0.0, Progress.EndTime - Progress.UpdateTime);
|
|
||||||
|
|
||||||
// Determine fade-in / fade-out blend
|
|
||||||
Progress.FadeInAlpha = 1.0;
|
|
||||||
Progress.FadeOutAlpha = 1.0;
|
|
||||||
if (Progress.FadeIn > 0.0) Progress.FadeInAlpha = FMath::Clamp(Progress.ElapsedTime / Progress.FadeIn, 0.0, 1.0);
|
|
||||||
if (Progress.FadeOut > 0.0) Progress.FadeOutAlpha = FMath::Clamp(Progress.TimeLeft / Progress.FadeOut, 0.0, 1.0);
|
|
||||||
Progress.FadeAlpha = FMath::Min(Progress.FadeInAlpha, Progress.FadeOutAlpha);
|
|
||||||
|
|
||||||
return Progress;
|
|
||||||
}
|
|
||||||
|
|
||||||
void UlxUtilityLibrary::ScriptedAnimationEvaluatorData(const UlxScriptedAnimations *Animations, double CurrentTime,
|
|
||||||
UAnimSequenceBase *&Sequence0, float &ExplicitTime0,
|
|
||||||
UAnimSequenceBase *&Sequence1, float &ExplicitTime1,
|
|
||||||
UAnimSequenceBase *&Sequence2, float &ExplicitTime2,
|
|
||||||
float &BaseAlpha, float &Sequence0Alpha, float &Sequence1Alpha, float &Sequence2Alpha)
|
|
||||||
{
|
|
||||||
Sequence0 = nullptr;
|
|
||||||
Sequence1 = nullptr;
|
|
||||||
Sequence2 = nullptr;
|
|
||||||
ExplicitTime0 = 0.0;
|
|
||||||
ExplicitTime1 = 0.0;
|
|
||||||
ExplicitTime2 = 0.0;
|
|
||||||
BaseAlpha = 0.0;
|
|
||||||
Sequence0Alpha = 0.0;
|
|
||||||
Sequence1Alpha = 0.0;
|
|
||||||
Sequence2Alpha = 0.0;
|
|
||||||
|
|
||||||
if (Animations != nullptr)
|
|
||||||
{
|
|
||||||
const TArray<FlxScriptedAnimation> &Anims = Animations->GetAnimations();
|
|
||||||
if (Anims.Num() > 0)
|
|
||||||
{
|
|
||||||
FlxScriptedAnimationProgress Progress = ScriptedAnimationProgress(Anims[0], CurrentTime);
|
|
||||||
Sequence0 = Progress.Sequence;
|
|
||||||
ExplicitTime0 = Progress.ElapsedTime;
|
|
||||||
Sequence0Alpha = Progress.FadeAlpha;
|
|
||||||
}
|
|
||||||
if (Anims.Num() > 1)
|
|
||||||
{
|
|
||||||
FlxScriptedAnimationProgress Progress = ScriptedAnimationProgress(Anims[1], CurrentTime);
|
|
||||||
Sequence1 = Progress.Sequence;
|
|
||||||
ExplicitTime1 = Progress.ElapsedTime;
|
|
||||||
Sequence1Alpha = Progress.FadeAlpha;
|
|
||||||
}
|
|
||||||
if (Anims.Num() > 2)
|
|
||||||
{
|
|
||||||
FlxScriptedAnimationProgress Progress = ScriptedAnimationProgress(Anims[2], CurrentTime);
|
|
||||||
Sequence2 = Progress.Sequence;
|
|
||||||
ExplicitTime2 = Progress.ElapsedTime;
|
|
||||||
Sequence2Alpha = Progress.FadeAlpha;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double AlphaTotal = Sequence0Alpha + Sequence1Alpha + Sequence2Alpha;
|
|
||||||
if (AlphaTotal > 1.0)
|
|
||||||
{
|
|
||||||
double Scale = 1.0 / AlphaTotal;
|
|
||||||
Sequence0Alpha *= Scale;
|
|
||||||
Sequence1Alpha *= Scale;
|
|
||||||
Sequence2Alpha *= Scale;
|
|
||||||
BaseAlpha = 0.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BaseAlpha = 1.0 - AlphaTotal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ElxUsedOrNotUsed UlxUtilityLibrary::IsKeyUsedByMappingContext(const FKey &Key, const UInputMappingContext *MappingContext)
|
ElxUsedOrNotUsed UlxUtilityLibrary::IsKeyUsedByMappingContext(const FKey &Key, const UInputMappingContext *MappingContext)
|
||||||
{
|
{
|
||||||
if (!MappingContext)
|
if (!MappingContext)
|
||||||
|
|||||||
@@ -14,89 +14,6 @@ class UEnhancedInputLocalPlayerSubsystem;
|
|||||||
class UAnimSequenceBase;
|
class UAnimSequenceBase;
|
||||||
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct INTEGRATION_API FlxScriptedAnimation
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
|
||||||
UAnimSequenceBase *Sequence;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double FadeIn = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double FadeOut = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double StartTime = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double AdjustedLength = 0.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
USTRUCT(BlueprintType)
|
|
||||||
struct INTEGRATION_API FlxScriptedAnimationProgress : public FlxScriptedAnimation
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double UpdateTime = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double EndTime = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double ElapsedTime = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double TimeLeft = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double FadeInAlpha = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double FadeOutAlpha = 0.0;
|
|
||||||
|
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, AdvancedDisplay)
|
|
||||||
double FadeAlpha = 0.0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
UCLASS(BlueprintType)
|
|
||||||
class INTEGRATION_API UlxScriptedAnimations : public UObject
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
private:
|
|
||||||
UPROPERTY()
|
|
||||||
int KeepCount = 3;
|
|
||||||
|
|
||||||
UPROPERTY()
|
|
||||||
TArray<FlxScriptedAnimation> Animations;
|
|
||||||
|
|
||||||
// If the number of elements in the array exceeds the count, discard.
|
|
||||||
//
|
|
||||||
void Keep(int n);
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Allow read-only access anywhere.
|
|
||||||
//
|
|
||||||
const TArray<FlxScriptedAnimation> &GetAnimations() const { return Animations; }
|
|
||||||
|
|
||||||
// Add a scripted animation to the end of the array.
|
|
||||||
//
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Scripted Animations", meta=(WorldContext = "WorldContextObject"))
|
|
||||||
void AddAnimation(
|
|
||||||
UObject *WorldContextObject, UAnimSequenceBase* Sequence, double FadeInTime = 0.2, double FadeOutTime = 0.2);
|
|
||||||
|
|
||||||
// Truncate all current animations: force them all to begin fading out.
|
|
||||||
//
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Luprex|Scripted Animations", meta=(WorldContext = "WorldContextObject"))
|
|
||||||
void FadeOutAll(UObject *WorldContextObject);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* UlxUtilityLibrary is for functions that are aren't particularly luprex-specific,
|
* UlxUtilityLibrary is for functions that are aren't particularly luprex-specific,
|
||||||
@@ -220,29 +137,6 @@ public:
|
|||||||
UFUNCTION(BlueprintPure, Category="Widget")
|
UFUNCTION(BlueprintPure, Category="Widget")
|
||||||
static void GetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel, FVector2D &UpperLeftXY, FVector2D &LowerRightXY);
|
static void GetPositionOfGridPanelMiddleCell(UGridPanel *GridPanel, FVector2D &UpperLeftXY, FVector2D &LowerRightXY);
|
||||||
|
|
||||||
// Calculate the progress of a Scripted Animation.
|
|
||||||
//
|
|
||||||
// Given a scripted animation and the current time, calculates
|
|
||||||
// how much time has elapsed, how much time is left, and several
|
|
||||||
// other parameters pertaining to the passage of time for
|
|
||||||
// this animation.
|
|
||||||
//
|
|
||||||
UFUNCTION(BlueprintPure, Category = "Luprex|Scripted Animations", meta=(BlueprintThreadSafe))
|
|
||||||
static FlxScriptedAnimationProgress ScriptedAnimationProgress(const FlxScriptedAnimation &Animation, double CurrentTime);
|
|
||||||
|
|
||||||
// Get the data to drive Sequence Evaluators and Multi Blend
|
|
||||||
//
|
|
||||||
// To apply scripted animations in an Anim Graph, you will need
|
|
||||||
// three sequence evaluators and a multi-blend node. This
|
|
||||||
// function outputs the input parameters for all of those nodes.
|
|
||||||
//
|
|
||||||
UFUNCTION(BlueprintPure, Category = "Luprex|Scripted Animations", meta=(BlueprintThreadSafe))
|
|
||||||
static void ScriptedAnimationEvaluatorData(const UlxScriptedAnimations *Animations, double CurrentTime,
|
|
||||||
UAnimSequenceBase *&Sequence0, float &ExplicitTime0,
|
|
||||||
UAnimSequenceBase *&Sequence1, float &ExplicitTime1,
|
|
||||||
UAnimSequenceBase *&Sequence2, float &ExplicitTime2,
|
|
||||||
float &BaseAlpha, float &Sequence0Alpha, float &Sequence1Alpha, float &Sequence2Alpha);
|
|
||||||
|
|
||||||
// Check if a given key is used by the specified mapping context.
|
// Check if a given key is used by the specified mapping context.
|
||||||
//
|
//
|
||||||
// This is true if the key is mapped to anything at all within
|
// This is true if the key is mapped to anything at all within
|
||||||
|
|||||||
Reference in New Issue
Block a user