338 lines
7.6 KiB
C++
338 lines
7.6 KiB
C++
// Copyright 2019-Present LexLiu. All Rights Reserved.
|
|
|
|
#include "LTweener.h"
|
|
#include "Curves/CurveFloat.h"
|
|
#include "LTween.h"
|
|
#include "Engine/World.h"
|
|
|
|
ULTweener::ULTweener()
|
|
{
|
|
tweenFunc.BindStatic(&ULTweener::OutCubic);//OutCubic default animation curve function
|
|
}
|
|
ULTweener* ULTweener::SetEase(ELTweenEase easetype)
|
|
{
|
|
if (elapseTime > 0 || startToTween)return this;
|
|
switch (easetype)
|
|
{
|
|
case ELTweenEase::Linear:
|
|
tweenFunc.BindStatic(&ULTweener::Linear);
|
|
break;
|
|
case ELTweenEase::InQuad:
|
|
tweenFunc.BindStatic(&ULTweener::InQuad);
|
|
break;
|
|
case ELTweenEase::OutQuad:
|
|
tweenFunc.BindStatic(&ULTweener::OutQuad);
|
|
break;
|
|
case ELTweenEase::InOutQuad:
|
|
tweenFunc.BindStatic(&ULTweener::InOutQuad);
|
|
break;
|
|
case ELTweenEase::InCubic:
|
|
tweenFunc.BindStatic(&ULTweener::InCubic);
|
|
break;
|
|
case ELTweenEase::OutCubic:
|
|
tweenFunc.BindStatic(&ULTweener::OutCubic);
|
|
break;
|
|
case ELTweenEase::InOutCubic:
|
|
tweenFunc.BindStatic(&ULTweener::InOutCubic);
|
|
break;
|
|
case ELTweenEase::InQuart:
|
|
tweenFunc.BindStatic(&ULTweener::InQuart);
|
|
break;
|
|
case ELTweenEase::OutQuart:
|
|
tweenFunc.BindStatic(&ULTweener::OutQuart);
|
|
break;
|
|
case ELTweenEase::InOutQuart:
|
|
tweenFunc.BindStatic(&ULTweener::InOutQuart);
|
|
break;
|
|
case ELTweenEase::InSine:
|
|
tweenFunc.BindStatic(&ULTweener::InSine);
|
|
break;
|
|
case ELTweenEase::OutSine:
|
|
tweenFunc.BindStatic(&ULTweener::OutSine);
|
|
break;
|
|
case ELTweenEase::InOutSine:
|
|
tweenFunc.BindStatic(&ULTweener::InOutSine);
|
|
break;
|
|
case ELTweenEase::InExpo:
|
|
tweenFunc.BindStatic(&ULTweener::InExpo);
|
|
break;
|
|
case ELTweenEase::OutExpo:
|
|
tweenFunc.BindStatic(&ULTweener::OutExpo);
|
|
break;
|
|
case ELTweenEase::InOutExpo:
|
|
tweenFunc.BindStatic(&ULTweener::InOutExpo);
|
|
break;
|
|
case ELTweenEase::InCirc:
|
|
tweenFunc.BindStatic(&ULTweener::InCirc);
|
|
break;
|
|
case ELTweenEase::OutCirc:
|
|
tweenFunc.BindStatic(&ULTweener::OutCirc);
|
|
break;
|
|
case ELTweenEase::InOutCirc:
|
|
tweenFunc.BindStatic(&ULTweener::InOutCirc);
|
|
break;
|
|
case ELTweenEase::InElastic:
|
|
tweenFunc.BindStatic(&ULTweener::InElastic);
|
|
break;
|
|
case ELTweenEase::OutElastic:
|
|
tweenFunc.BindStatic(&ULTweener::OutElastic);
|
|
break;
|
|
case ELTweenEase::InOutElastic:
|
|
tweenFunc.BindStatic(&ULTweener::InOutElastic);
|
|
break;
|
|
case ELTweenEase::InBack:
|
|
tweenFunc.BindStatic(&ULTweener::InBack);
|
|
break;
|
|
case ELTweenEase::OutBack:
|
|
tweenFunc.BindStatic(&ULTweener::OutBack);
|
|
break;
|
|
case ELTweenEase::InOutBack:
|
|
tweenFunc.BindStatic(&ULTweener::InOutBack);
|
|
break;
|
|
case ELTweenEase::InBounce:
|
|
tweenFunc.BindStatic(&ULTweener::InBounce);
|
|
break;
|
|
case ELTweenEase::OutBounce:
|
|
tweenFunc.BindStatic(&ULTweener::OutBounce);
|
|
break;
|
|
case ELTweenEase::InOutBounce:
|
|
tweenFunc.BindStatic(&ULTweener::InOutBounce);
|
|
break;
|
|
case ELTweenEase::CurveFloat:
|
|
tweenFunc.BindUObject(this, &ULTweener::CurveFloat);
|
|
break;
|
|
}
|
|
return this;
|
|
}
|
|
ULTweener* ULTweener::SetDelay(float newDelay)
|
|
{
|
|
if (elapseTime > 0 || startToTween)return this;
|
|
this->delay = newDelay;
|
|
if (this->delay < 0)
|
|
{
|
|
this->delay = 0;
|
|
}
|
|
return this;
|
|
}
|
|
ULTweener* ULTweener::SetLoop(ELTweenLoop newLoopType, int32 newLoopCount)
|
|
{
|
|
if (elapseTime > 0 || startToTween)return this;
|
|
this->loopType = newLoopType;
|
|
this->maxLoopCount = newLoopCount;
|
|
return this;
|
|
}
|
|
ULTweener* ULTweener::SetEaseCurve(UCurveFloat* newCurve)
|
|
{
|
|
if (IsValid(newCurve))
|
|
{
|
|
SetEase(ELTweenEase::CurveFloat);
|
|
curveFloat = newCurve;
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LTween, Error, TEXT("[ULTweener::SetEaseCurve]newCurve is not valid!"));
|
|
}
|
|
return this;
|
|
}
|
|
|
|
ULTweener* ULTweener::SetCurveFloat(UCurveFloat* newCurveFloat)
|
|
{
|
|
if (elapseTime > 0 || startToTween)return this;
|
|
curveFloat = newCurveFloat;
|
|
return this;
|
|
}
|
|
ULTweener* ULTweener::SetAffectByGamePause(bool value)
|
|
{
|
|
affectByGamePause = value;
|
|
return this;
|
|
}
|
|
ULTweener* ULTweener::SetAffectByTimeDilation(bool value)
|
|
{
|
|
affectByTimeDilation = value;
|
|
return this;
|
|
}
|
|
|
|
bool ULTweener::ToNext(float deltaTime, float unscaledDeltaTime)
|
|
{
|
|
if (auto world = GetWorld())
|
|
{
|
|
if (world->IsPaused() && affectByGamePause)return true;
|
|
}
|
|
if (isMarkedToKill)return false;
|
|
if (isMarkedPause)return true;//no need to tick time if pause
|
|
return this->ToNextWithElapsedTime(elapseTime + (affectByTimeDilation ? deltaTime : unscaledDeltaTime));
|
|
}
|
|
bool ULTweener::ToNextWithElapsedTime(float InElapseTime)
|
|
{
|
|
this->elapseTime = InElapseTime;
|
|
if (elapseTime > delay)//if elapseTime bigger than delay, do animation
|
|
{
|
|
if (!startToTween)
|
|
{
|
|
startToTween = true;
|
|
//set initialize value
|
|
OnStartGetValue();
|
|
//execute callback
|
|
onCycleStartCpp.ExecuteIfBound();
|
|
onStartCpp.ExecuteIfBound();
|
|
}
|
|
|
|
float elapseTimeWithoutDelay = elapseTime - delay;
|
|
float currentTime = elapseTimeWithoutDelay - duration * loopCycleCount;
|
|
if (currentTime >= duration)
|
|
{
|
|
bool returnValue = true;
|
|
loopCycleCount++;
|
|
|
|
TweenAndApplyValue(reverseTween ? 0 : duration);
|
|
onUpdateCpp.ExecuteIfBound(1.0f);
|
|
onCycleCompleteCpp.ExecuteIfBound();
|
|
if (loopType == ELTweenLoop::Once)
|
|
{
|
|
onCompleteCpp.ExecuteIfBound();
|
|
returnValue = false;
|
|
}
|
|
else if (maxLoopCount <= -1)//infinite loop
|
|
{
|
|
onCycleStartCpp.ExecuteIfBound();//start new cycle callback
|
|
returnValue = true;
|
|
}
|
|
else
|
|
{
|
|
if (loopCycleCount >= maxLoopCount)//reach end cycle
|
|
{
|
|
onCompleteCpp.ExecuteIfBound();
|
|
returnValue = false;
|
|
}
|
|
else//not reach end cycle
|
|
{
|
|
onCycleStartCpp.ExecuteIfBound();//start new cycle callback
|
|
returnValue = true;
|
|
}
|
|
}
|
|
switch (loopType)
|
|
{
|
|
case ELTweenLoop::Restart:
|
|
{
|
|
SetValueForRestart();
|
|
}
|
|
break;
|
|
case ELTweenLoop::Yoyo:
|
|
{
|
|
reverseTween = !reverseTween;
|
|
SetValueForYoyo();
|
|
}
|
|
break;
|
|
case ELTweenLoop::Incremental:
|
|
{
|
|
SetValueForIncremental();
|
|
}
|
|
break;
|
|
}
|
|
return returnValue;
|
|
}
|
|
else
|
|
{
|
|
if (reverseTween)
|
|
{
|
|
currentTime = duration - currentTime;
|
|
}
|
|
TweenAndApplyValue(currentTime);
|
|
onUpdateCpp.ExecuteIfBound(currentTime / duration);
|
|
return true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return true;//waiting delay
|
|
}
|
|
}
|
|
|
|
void ULTweener::Kill(bool callComplete)
|
|
{
|
|
if (callComplete)
|
|
{
|
|
onCompleteCpp.ExecuteIfBound();
|
|
}
|
|
isMarkedToKill = true;
|
|
}
|
|
|
|
void ULTweener::ForceComplete()
|
|
{
|
|
isMarkedToKill = true;
|
|
elapseTime = delay + duration;
|
|
TweenAndApplyValue(duration);
|
|
onUpdateCpp.ExecuteIfBound(1.0f);
|
|
onCompleteCpp.ExecuteIfBound();
|
|
}
|
|
|
|
void ULTweener::Restart()
|
|
{
|
|
if (elapseTime == 0)
|
|
{
|
|
return;
|
|
}
|
|
isMarkedPause = false;//incase it is paused.
|
|
//reset parameter to initial
|
|
loopCycleCount = 0;
|
|
reverseTween = false;
|
|
SetOriginValueForRestart();
|
|
|
|
this->ToNextWithElapsedTime(0);
|
|
}
|
|
|
|
void ULTweener::Goto(float timePoint)
|
|
{
|
|
timePoint = FMath::Clamp(timePoint, 0.0f, duration);
|
|
//reset parameter to initial
|
|
loopCycleCount = 0;
|
|
reverseTween = false;
|
|
|
|
this->ToNextWithElapsedTime(timePoint);
|
|
}
|
|
|
|
float ULTweener::GetProgress()const
|
|
{
|
|
if (elapseTime > delay)
|
|
{
|
|
float elapseTimeWithoutDelay = elapseTime - delay;
|
|
float currentTime = elapseTimeWithoutDelay - duration * loopCycleCount;
|
|
if (currentTime >= duration)
|
|
{
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
if (reverseTween)
|
|
{
|
|
currentTime = duration - currentTime;
|
|
}
|
|
return currentTime / duration;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
ULTweener* ULTweener::SetTickType(ELTweenTickType value)
|
|
{
|
|
if (elapseTime > 0 || startToTween)return this;
|
|
this->tickType = value;
|
|
return this;
|
|
}
|
|
|
|
float ULTweener::CurveFloat(float c, float b, float t, float d)
|
|
{
|
|
if (d < KINDA_SMALL_NUMBER)return c + b;
|
|
if (curveFloat.IsValid())
|
|
{
|
|
return curveFloat->GetFloatValue(t / d) * c + b;
|
|
}
|
|
else
|
|
{
|
|
UE_LOG(LTween, Warning, TEXT("[ULTweener::CurveFloat]CurveFloat not valid! Fallback to linear. You should always call SetCurveFloat(and pass a valid curve) if set Easetype to CurveFloat."));
|
|
return Linear(c, b, t, d);
|
|
}
|
|
} |