#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 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 &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 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); };