Skip to content

Commit

Permalink
Vector and LinearColor timelines added
Browse files Browse the repository at this point in the history
  • Loading branch information
zompi2 committed Dec 11, 2024
1 parent f492493 commit 082c4d8
Show file tree
Hide file tree
Showing 8 changed files with 350 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2024 Damian Nowakowski. All rights reserved.

#include "ECFTimelineLinearColorBP.h"
#include "EnhancedCodeFlow.h"

ECF_PRAGMA_DISABLE_OPTIMIZATION

UECFTimelineLinearColorBP* UECFTimelineLinearColorBP::ECFTimelineLinearColor(const UObject* WorldContextObject, FLinearColor StartValue, FLinearColor StopValue, float Time, FECFActionSettings Settings, FECFHandleBP& Handle, EECFBlendFunc BlendFunc /*= EECFBlendFunc::ECFBlend_Linear*/, float BlendExp /*= 1.f*/)
{
UECFTimelineLinearColorBP* Proxy = NewObject<UECFTimelineLinearColorBP>();
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::AddTimelineLinearColor(WorldContextObject,
StartValue, StopValue, Time,
[Proxy](FLinearColor Value, float Time)
{
if (IsProxyValid(Proxy))
{
Proxy->OnTick.Broadcast(Value, Time, false);
}
},
[Proxy](FLinearColor Value, float Time, bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnFinished.Broadcast(Value, Time, false);
Proxy->ClearAsyncBPAction();
}
},
BlendFunc, BlendExp, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}

ECF_PRAGMA_ENABLE_OPTIMIZATION
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2024 Damian Nowakowski. All rights reserved.

#pragma once

#include "../ECFActionBP.h"
#include "ECFTypes.h"
#include "ECFTimelineLinearColorBP.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnECFTimelineLinearColorBPEvent, FLinearColor, Value, float, Time, bool, bStopped);

UCLASS()
class ENHANCEDCODEFLOW_API UECFTimelineLinearColorBP : public UECFActionBP
{
GENERATED_BODY()

public:

UPROPERTY(BlueprintAssignable)
FOnECFTimelineLinearColorBPEvent OnTick;

UPROPERTY(BlueprintAssignable)
FOnECFTimelineLinearColorBPEvent OnFinished;

UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject", AdvancedDisplay = "Settings, BlendFunc, BlendExp", ToolTip = "Adds a simple LinearColor timeline that runs in a given range during a given time.", DisplayName = "ECF - Timeline LinearColor"), Category = "ECF")
static UECFTimelineLinearColorBP* ECFTimelineLinearColor(const UObject* WorldContextObject, FLinearColor StartValue, FLinearColor StopValue, float Time, FECFActionSettings Settings, FECFHandleBP& Handle, EECFBlendFunc BlendFunc = EECFBlendFunc::ECFBlend_Linear, float BlendExp = 1.f);
};
38 changes: 38 additions & 0 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFTimelineVectorBP.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2024 Damian Nowakowski. All rights reserved.

#include "ECFTimelineVectorBP.h"
#include "EnhancedCodeFlow.h"

ECF_PRAGMA_DISABLE_OPTIMIZATION

UECFTimelineVectorBP* UECFTimelineVectorBP::ECFTimelineVector(const UObject* WorldContextObject, FVector StartValue, FVector StopValue, float Time, FECFActionSettings Settings, FECFHandleBP& Handle, EECFBlendFunc BlendFunc /*= EECFBlendFunc::ECFBlend_Linear*/, float BlendExp /*= 1.f*/)
{
UECFTimelineVectorBP* Proxy = NewObject<UECFTimelineVectorBP>();
if (Proxy)
{
Proxy->Init(WorldContextObject, Settings);
Proxy->Proxy_Handle = FFlow::AddTimelineVector(WorldContextObject,
StartValue, StopValue, Time,
[Proxy](FVector Value, float Time)
{
if (IsProxyValid(Proxy))
{
Proxy->OnTick.Broadcast(Value, Time, false);
}
},
[Proxy](FVector Value, float Time, bool bStopped)
{
if (IsProxyValid(Proxy))
{
Proxy->OnFinished.Broadcast(Value, Time, false);
Proxy->ClearAsyncBPAction();
}
},
BlendFunc, BlendExp, Settings);
Handle = FECFHandleBP(Proxy->Proxy_Handle);
}

return Proxy;
}

ECF_PRAGMA_ENABLE_OPTIMIZATION
26 changes: 26 additions & 0 deletions Source/EnhancedCodeFlow/Private/BP/Actions/ECFTimelineVectorBP.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright (c) 2024 Damian Nowakowski. All rights reserved.

#pragma once

#include "../ECFActionBP.h"
#include "ECFTypes.h"
#include "ECFTimelineVectorBP.generated.h"

DECLARE_DYNAMIC_MULTICAST_DELEGATE_ThreeParams(FOnECFTimelineVectorBPEvent, FVector, Value, float, Time, bool, bStopped);

UCLASS()
class ENHANCEDCODEFLOW_API UECFTimelineVectorBP : public UECFActionBP
{
GENERATED_BODY()

public:

UPROPERTY(BlueprintAssignable)
FOnECFTimelineVectorBPEvent OnTick;

UPROPERTY(BlueprintAssignable)
FOnECFTimelineVectorBPEvent OnFinished;

UFUNCTION(BlueprintCallable, meta = (BlueprintInternalUseOnly = "true", WorldContext = "WorldContextObject", AdvancedDisplay = "Settings, BlendFunc, BlendExp", ToolTip = "Adds a simple vector timeline that runs in a given range during a given time.", DisplayName = "ECF - Timeline Vector"), Category = "ECF")
static UECFTimelineVectorBP* ECFTimelineVector(const UObject* WorldContextObject, FVector StartValue, FVector StopValue, float Time, FECFActionSettings Settings, FECFHandleBP& Handle, EECFBlendFunc BlendFunc = EECFBlendFunc::ECFBlend_Linear, float BlendExp = 1.f);
};
54 changes: 52 additions & 2 deletions Source/EnhancedCodeFlow/Private/EnhancedCodeFlow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
#include "CodeFlowActions/ECFWaitAndExecute_WithDeltaTime.h"
#include "CodeFlowActions/ECFWhileTrueExecute.h"
#include "CodeFlowActions/ECFTimeline.h"
#include "CodeFlowActions/ECFTimelineVector.h"
#include "CodeFlowActions/ECFTimelineLinearColor.h"
#include "CodeFlowActions/ECFCustomTimeline.h"
#include "CodeFlowActions/ECFTimeLock.h"
#include "CodeFlowActions/ECFDoOnce.h"
Expand Down Expand Up @@ -293,15 +295,15 @@ void FFlow::RemoveAllWhileTrueExecutes(const UObject* WorldContextObject, bool b

/*^^^ Timeline ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

FECFHandle FFlow::AddTimeline(const UObject* InOwner, float InStartValue, float InStopValue, float InTime, TUniqueFunction<void(float/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(float/* Value*/, float/* Time*/, bool/* bStopped*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 0.f*/, const FECFActionSettings& Settings/* = {}*/)
FECFHandle FFlow::AddTimeline(const UObject* InOwner, float InStartValue, float InStopValue, float InTime, TUniqueFunction<void(float/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(float/* Value*/, float/* Time*/, bool/* bStopped*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 1.f*/, const FECFActionSettings& Settings/* = {}*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(InOwner))
return ECF->AddAction<UECFTimeline>(InOwner, Settings, FECFInstanceId(), InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), MoveTemp(InCallbackFunc), InBlendFunc, InBlendExp);
else
return FECFHandle();
}

FECFHandle FFlow::AddTimeline(const UObject* InOwner, float InStartValue, float InStopValue, float InTime, TUniqueFunction<void(float/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(float/* Value*/, float/* Time*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 0.f*/, const FECFActionSettings& Settings/* = {}*/)
FECFHandle FFlow::AddTimeline(const UObject* InOwner, float InStartValue, float InStopValue, float InTime, TUniqueFunction<void(float/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(float/* Value*/, float/* Time*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 1.f*/, const FECFActionSettings& Settings/* = {}*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(InOwner))
return ECF->AddAction<UECFTimeline>(InOwner, Settings, FECFInstanceId(), InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), MoveTemp(InCallbackFunc), InBlendFunc, InBlendExp);
Expand All @@ -315,6 +317,54 @@ void FFlow::RemoveAllTimelines(const UObject* WorldContextObject, bool bComplete
ECF->RemoveActionsOfClass<UECFTimeline>(bComplete, InOwner);
}

/*^^^ Timeline Vector ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

FECFHandle FFlow::AddTimelineVector(const UObject* InOwner, FVector InStartValue, FVector InStopValue, float InTime, TUniqueFunction<void(FVector/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(FVector/* Value*/, float/* Time*/, bool/* bStopped*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 1.f*/, const FECFActionSettings& Settings/* = {}*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(InOwner))
return ECF->AddAction<UECFTimelineVector>(InOwner, Settings, FECFInstanceId(), InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), MoveTemp(InCallbackFunc), InBlendFunc, InBlendExp);
else
return FECFHandle();
}

FECFHandle FFlow::AddTimelineVector(const UObject* InOwner, FVector InStartValue, FVector InStopValue, float InTime, TUniqueFunction<void(FVector/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(FVector/* Value*/, float/* Time*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 1.f*/, const FECFActionSettings& Settings/* = {}*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(InOwner))
return ECF->AddAction<UECFTimelineVector>(InOwner, Settings, FECFInstanceId(), InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), MoveTemp(InCallbackFunc), InBlendFunc, InBlendExp);
else
return FECFHandle();
}

void FFlow::RemoveAllTimelinesVector(const UObject* WorldContextObject, bool bComplete/* = false*/, UObject* InOwner/* = nullptr*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(WorldContextObject))
ECF->RemoveActionsOfClass<UECFTimelineVector>(bComplete, InOwner);
}

/*^^^ Timeline LinearColor ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

FECFHandle FFlow::AddTimelineLinearColor(const UObject* InOwner, FLinearColor InStartValue, FLinearColor InStopValue, float InTime, TUniqueFunction<void(FLinearColor/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(FLinearColor/* Value*/, float/* Time*/, bool/* bStopped*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 1.f*/, const FECFActionSettings& Settings/* = {}*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(InOwner))
return ECF->AddAction<UECFTimelineLinearColor>(InOwner, Settings, FECFInstanceId(), InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), MoveTemp(InCallbackFunc), InBlendFunc, InBlendExp);
else
return FECFHandle();
}

FECFHandle FFlow::AddTimelineLinearColor(const UObject* InOwner, FLinearColor InStartValue, FLinearColor InStopValue, float InTime, TUniqueFunction<void(FLinearColor/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(FLinearColor/* Value*/, float/* Time*/)>&& InCallbackFunc/* = nullptr*/, EECFBlendFunc InBlendFunc/* = EECFBlendFunc::ECFBlend_Linear*/, float InBlendExp/* = 1.f*/, const FECFActionSettings& Settings/* = {}*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(InOwner))
return ECF->AddAction<UECFTimelineLinearColor>(InOwner, Settings, FECFInstanceId(), InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), MoveTemp(InCallbackFunc), InBlendFunc, InBlendExp);
else
return FECFHandle();
}

void FFlow::RemoveAllTimelinesLinearColor(const UObject* WorldContextObject, bool bComplete/* = false*/, UObject* InOwner/* = nullptr*/)
{
if (UECFSubsystem* ECF = UECFSubsystem::Get(WorldContextObject))
ECF->RemoveActionsOfClass<UECFTimelineLinearColor>(bComplete, InOwner);
}

/*^^^ Custom Timeline ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/

FECFHandle FFlow::AddCustomTimeline(const UObject* InOwner, UCurveFloat* CurveFloat, TUniqueFunction<void(float/* Value*/, float/* Time*/)>&& InTickFunc, TUniqueFunction<void(float/* Value*/, float/* Time*/, bool/* bStopped*/)>&& InCallbackFunc/* = nullptr*/, const FECFActionSettings& Settings/* = {}*/)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
// Copyright (c) 2024 Damian Nowakowski. All rights reserved.

#pragma once

#include "ECFActionBase.h"
#include "ECFTypes.h"
#include "ECFTimelineLinearColor.generated.h"

ECF_PRAGMA_DISABLE_OPTIMIZATION

UCLASS()
class ENHANCEDCODEFLOW_API UECFTimelineLinearColor: public UECFActionBase
{
GENERATED_BODY()

friend class UECFSubsystem;

protected:

TUniqueFunction<void(FLinearColor, float)> TickFunc;
TUniqueFunction<void(FLinearColor, float, bool)> CallbackFunc;
TUniqueFunction<void(FLinearColor, float)> CallbackFunc_NoStopped;
FLinearColor StartValue;
FLinearColor StopValue;
float Time;
EECFBlendFunc BlendFunc;
float BlendExp;

float CurrentTime;
FLinearColor CurrentValue;

bool Setup(FLinearColor InStartValue, FLinearColor InStopValue, float InTime, TUniqueFunction<void(FLinearColor, float)>&& InTickFunc, TUniqueFunction<void(FLinearColor, float, bool)>&& InCallbackFunc, EECFBlendFunc InBlendFunc, float InBlendExp)
{
StartValue = InStartValue;
StopValue = InStopValue;
Time = InTime;

TickFunc = MoveTemp(InTickFunc);
CallbackFunc = MoveTemp(InCallbackFunc);

BlendFunc = InBlendFunc;
BlendExp = InBlendExp;

if (TickFunc && Time > 0 && BlendExp != 0 && StartValue != StopValue)
{
SetMaxActionTime(Time);
CurrentTime = 0.f;
return true;
}
else
{
ensureMsgf(false, TEXT("ECF - Timeline Linear Color failed to start. Are you sure the Ticking time is greater than 0 and Ticking Function are set properly? /n Remember, that BlendExp must be different than zero and StartValue and StopValue must not be the same!"));
return false;
}
}

bool Setup(FLinearColor InStartValue, FLinearColor InStopValue, float InTime, TUniqueFunction<void(FLinearColor, float)>&& InTickFunc, TUniqueFunction<void(FLinearColor, float)>&& InCallbackFunc, EECFBlendFunc InBlendFunc, float InBlendExp)
{
CallbackFunc_NoStopped = MoveTemp(InCallbackFunc);
return Setup(InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), [this](FLinearColor FwdValue, float FwdTime, bool bStopped)
{
if (CallbackFunc_NoStopped)
{
CallbackFunc_NoStopped(FwdValue, FwdTime);
}
}, InBlendFunc, InBlendExp);
}

void Tick(float DeltaTime) override
{
#if STATS
DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Timeline Linear Color - Tick"), STAT_ECFDETAILS_TIMELINE, STATGROUP_ECFDETAILS);
#endif
CurrentTime = FMath::Clamp(CurrentTime + DeltaTime, 0.f, Time);

const float LerpValue = CurrentTime / Time;

switch (BlendFunc)
{
case EECFBlendFunc::ECFBlend_Linear:
CurrentValue = FMath::Lerp(StartValue, StopValue, LerpValue);
break;
case EECFBlendFunc::ECFBlend_Cubic:
CurrentValue = FMath::CubicInterp(StartValue, FLinearColor::Black, StopValue, FLinearColor::Black, LerpValue);
break;
case EECFBlendFunc::ECFBlend_EaseIn:
CurrentValue = FMath::Lerp(StartValue, StopValue, FMath::Pow(LerpValue, BlendExp));
break;
case EECFBlendFunc::ECFBlend_EaseOut:
CurrentValue = FMath::Lerp(StartValue, StopValue, FMath::Pow(LerpValue, 1.f / BlendExp));
break;
case EECFBlendFunc::ECFBlend_EaseInOut:
CurrentValue = FMath::InterpEaseInOut(StartValue, StopValue, LerpValue, BlendExp);
break;
}

TickFunc(CurrentValue, CurrentTime);

if (LerpValue >= 1.f)
{
Complete(false);
MarkAsFinished();
}
}

void Complete(bool bStopped) override
{
if (CallbackFunc)
{
CallbackFunc(CurrentValue, CurrentTime, bStopped);
}
}
};

ECF_PRAGMA_ENABLE_OPTIMIZATION
17 changes: 15 additions & 2 deletions Source/EnhancedCodeFlow/Public/CodeFlowActions/ECFTimelineVector.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ class ENHANCEDCODEFLOW_API UECFTimelineVector : public UECFActionBase

TUniqueFunction<void(FVector, float)> TickFunc;
TUniqueFunction<void(FVector, float, bool)> CallbackFunc;
TUniqueFunction<void(FVector, float)> CallbackFunc_NoStopped;
FVector StartValue;
FVector StopValue;
float Time;
Expand Down Expand Up @@ -48,15 +49,27 @@ class ENHANCEDCODEFLOW_API UECFTimelineVector : public UECFActionBase
}
else
{
ensureMsgf(false, TEXT("ECF - Timeline failed to start. Are you sure the Ticking time is greater than 0 and Ticking Function are set properly? /n Remember, that BlendExp must be different than zero and StartValue and StopValue must not be the same!"));
ensureMsgf(false, TEXT("ECF - Timeline Vector failed to start. Are you sure the Ticking time is greater than 0 and Ticking Function are set properly? /n Remember, that BlendExp must be different than zero and StartValue and StopValue must not be the same!"));
return false;
}
}

bool Setup(FVector InStartValue, FVector InStopValue, float InTime, TUniqueFunction<void(FVector, float)>&& InTickFunc, TUniqueFunction<void(FVector, float)>&& InCallbackFunc, EECFBlendFunc InBlendFunc, float InBlendExp)
{
CallbackFunc_NoStopped = MoveTemp(InCallbackFunc);
return Setup(InStartValue, InStopValue, InTime, MoveTemp(InTickFunc), [this](FVector FwdValue, float FwdTime, bool bStopped)
{
if (CallbackFunc_NoStopped)
{
CallbackFunc_NoStopped(FwdValue, FwdTime);
}
}, InBlendFunc, InBlendExp);
}

void Tick(float DeltaTime) override
{
#if STATS
DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Timeline - Tick"), STAT_ECFDETAILS_TIMELINE, STATGROUP_ECFDETAILS);
DECLARE_SCOPE_CYCLE_COUNTER(TEXT("Timeline Vector - Tick"), STAT_ECFDETAILS_TIMELINE, STATGROUP_ECFDETAILS);
#endif
CurrentTime = FMath::Clamp(CurrentTime + DeltaTime, 0.f, Time);

Expand Down
Loading

0 comments on commit 082c4d8

Please sign in to comment.