2025-10-14 20:24:37 -04:00
|
|
|
#include "ScriptedAnimation.h"
|
2025-10-27 18:18:35 -04:00
|
|
|
#include "Engine/Engine.h"
|
2025-10-14 20:24:37 -04:00
|
|
|
|
|
|
|
|
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(
|
2025-10-27 18:18:35 -04:00
|
|
|
UObject* WorldContextObject, UAnimSequenceBase* Sequence, double FadeInTime, double FadeOutTime,
|
|
|
|
|
int64 AnimationStepID, bool ContinueWhenPaused)
|
2025-10-14 20:24:37 -04:00
|
|
|
{
|
|
|
|
|
check(KeepCount >= 1);
|
|
|
|
|
FlxScriptedAnimation Result;
|
|
|
|
|
|
|
|
|
|
// Get World Time
|
2025-10-27 18:18:35 -04:00
|
|
|
FlxWorldClocks Clocks = UlxScriptedAnimationLibrary::GetAllWorldClocks(WorldContextObject);
|
|
|
|
|
double CurrentTime = ContinueWhenPaused ? Clocks.RealTime : Clocks.WorldTime;
|
2025-10-14 20:24:37 -04:00
|
|
|
|
|
|
|
|
// Get the animation Length.
|
|
|
|
|
double Length = (Sequence ? static_cast<double>(Sequence->GetPlayLength()) : 0.0);
|
|
|
|
|
|
|
|
|
|
// Fill the static setup fields
|
2025-10-27 18:18:35 -04:00
|
|
|
Result.Sequence = Sequence;
|
|
|
|
|
Result.ContinueWhenPaused = ContinueWhenPaused;
|
|
|
|
|
Result.AnimationStepID = AnimationStepID;
|
|
|
|
|
Result.FadeInDuration = FadeInTime;
|
|
|
|
|
Result.FadeOutDuration = FadeOutTime;
|
|
|
|
|
Result.StartTime = CurrentTime;
|
|
|
|
|
Result.EndTime = CurrentTime + Length;
|
2025-10-14 20:24:37 -04:00
|
|
|
|
|
|
|
|
Keep(KeepCount - 1);
|
|
|
|
|
Animations.Insert(Result, 0);
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-27 18:18:35 -04:00
|
|
|
void UlxScriptedAnimations::FadeGarbage(const UObject *WorldContextObject, TArray<int64> KeepIDs)
|
2025-10-14 20:24:37 -04:00
|
|
|
{
|
2025-10-27 18:18:35 -04:00
|
|
|
FlxWorldClocks Clocks = UlxScriptedAnimationLibrary::GetAllWorldClocks(WorldContextObject);
|
2025-10-14 20:24:37 -04:00
|
|
|
for (int i = 0; i < Animations.Num(); i++)
|
|
|
|
|
{
|
|
|
|
|
FlxScriptedAnimation &Anim = Animations[i];
|
2025-10-27 18:18:35 -04:00
|
|
|
if ((Anim.AnimationStepID > 0) && (!KeepIDs.Contains(Anim.AnimationStepID)))
|
2025-10-14 20:24:37 -04:00
|
|
|
{
|
2025-10-27 18:18:35 -04:00
|
|
|
Anim.InitiateFadeOut(Anim.ChooseCorrectClock(Clocks), 0.2);
|
2025-10-14 20:24:37 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-27 18:18:35 -04:00
|
|
|
void UlxScriptedAnimationLibrary::ScriptedAnimationEvaluatorData(
|
|
|
|
|
const UlxScriptedAnimations *Animations,
|
|
|
|
|
const FlxWorldClocks &WorldClocks,
|
2025-10-14 20:24:37 -04:00
|
|
|
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];
|
2025-10-27 18:18:35 -04:00
|
|
|
double CurrentTime = Anim.ChooseCorrectClock(WorldClocks);
|
2025-10-14 20:24:37 -04:00
|
|
|
Sequence0 = Anim.Sequence;
|
|
|
|
|
ExplicitTime0 = Anim.ClampedElapsedTime(CurrentTime);
|
|
|
|
|
Sequence0Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
|
|
|
|
|
}
|
|
|
|
|
if (Anims.Num() > 1)
|
|
|
|
|
{
|
|
|
|
|
const FlxScriptedAnimation &Anim = Anims[1];
|
2025-10-27 18:18:35 -04:00
|
|
|
double CurrentTime = Anim.ChooseCorrectClock(WorldClocks);
|
2025-10-14 20:24:37 -04:00
|
|
|
Sequence1 = Anim.Sequence;
|
|
|
|
|
ExplicitTime1 = Anim.ClampedElapsedTime(CurrentTime);
|
|
|
|
|
Sequence1Alpha = Anim.CalcFadeInOutAlpha(CurrentTime);
|
|
|
|
|
}
|
|
|
|
|
if (Anims.Num() > 2)
|
|
|
|
|
{
|
|
|
|
|
const FlxScriptedAnimation &Anim = Anims[2];
|
2025-10-27 18:18:35 -04:00
|
|
|
double CurrentTime = Anim.ChooseCorrectClock(WorldClocks);
|
2025-10-14 20:24:37 -04:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-27 18:18:35 -04:00
|
|
|
FlxWorldClocks UlxScriptedAnimationLibrary::GetAllWorldClocks(const UObject *WorldContextObject)
|
|
|
|
|
{
|
|
|
|
|
UWorld* World = GEngine->GetWorldFromContextObjectChecked(WorldContextObject);
|
|
|
|
|
FlxWorldClocks Result;
|
|
|
|
|
if (World != nullptr)
|
|
|
|
|
{
|
|
|
|
|
Result.WorldTime = World->GetTimeSeconds();
|
|
|
|
|
Result.RealTime = World->GetRealTimeSeconds();
|
|
|
|
|
}
|
|
|
|
|
return Result;
|
|
|
|
|
}
|