// Copyright 2025 https://yuewu.dev/en All Rights Reserved. #pragma once #include "Kismet/BlueprintFunctionLibrary.h" #include "GMS_Math.generated.h" UCLASS(Meta = (BlueprintThreadSafe)) class GENERICMOVEMENTSYSTEM_API UGMS_Math : public UBlueprintFunctionLibrary { GENERATED_BODY() public: static constexpr auto Ln2{0.6931471805599453f}; // FMath::Loge(2.0f). public: UFUNCTION(BlueprintCallable, BlueprintPure, Category = "GMS|Math Utility", Meta = (ReturnDisplayName = "Value")) static float Clamp01(float Value); UFUNCTION(BlueprintCallable, BlueprintPure, Category = "GMS|Math Utility", Meta = (ReturnDisplayName = "Value")) static float LerpClamped(float From, float To, float Ratio); //Output the frame-rate stable alpha used for smoothly lerp current to target. UFUNCTION(BlueprintCallable, BlueprintPure, Category = "GMS|Math Utility", Meta = (ReturnDisplayName = "Alpha")) static float DamperExactAlpha(float DeltaTime, float HalfLife); // HalfLife is the time it takes for the distance to the target to be reduced by half. template static ValueType DamperExact(const ValueType& Current, const ValueType& Target, float DeltaTime, float HalfLife); }; inline float UGMS_Math::Clamp01(const float Value) { return Value > 0.0f ? Value < 1.0f ? Value : 1.0f : 0.0f; } inline float UGMS_Math::LerpClamped(const float From, const float To, const float Ratio) { return From + (To - From) * Clamp01(Ratio); } inline float UGMS_Math::DamperExactAlpha(const float DeltaTime, const float HalfLife) { // https://theorangeduck.com/page/spring-roll-call#exactdamper return 1.0f - FMath::InvExpApprox(Ln2 / (HalfLife + UE_SMALL_NUMBER) * DeltaTime); } template ValueType UGMS_Math::DamperExact(const ValueType& Current, const ValueType& Target, const float DeltaTime, const float HalfLife) { return FMath::Lerp(Current, Target, DamperExactAlpha(DeltaTime, HalfLife)); }