mirror of
https://gitlab.com/MaddoScientisto/cirnogodot.git
synced 2026-06-01 07:45:33 +00:00
423 lines
12 KiB
C#
423 lines
12 KiB
C#
using System;
|
|
using GTweens.Easings;
|
|
using GTweens.Enums;
|
|
using GTweens.TweenBehaviours;
|
|
|
|
namespace GTweens.Tweens
|
|
{
|
|
/// <summary>
|
|
/// Represents the core item for building tweening animations.
|
|
/// </summary>
|
|
public sealed class GTween
|
|
{
|
|
public event Action? OnStartAction;
|
|
public event Action? OnTickAction;
|
|
public event Action? OnLoopAction;
|
|
public event Action? OnResetAction;
|
|
public event Action? OnCompleteAction;
|
|
public event Action? OnKillAction;
|
|
public event Action? OnCompleteOrKillAction;
|
|
public event Action<float>? OnTimeScaleChangedAction;
|
|
|
|
public ITweenBehaviour Behaviour { get; }
|
|
public float TimeScale { get; private set; } = 1;
|
|
|
|
public float Delay { get; private set; }
|
|
|
|
public int Loops { get; private set; }
|
|
public ResetMode LoopResetMode { get; private set; }
|
|
|
|
public bool IsNested { get; set; }
|
|
|
|
public bool IsPlaying { get; private set; }
|
|
public bool IsPaused { get; private set; }
|
|
public bool IsCompleted { get; private set; }
|
|
public bool IsKilled { get; private set; }
|
|
public bool IsCompletedOrKilled => IsCompleted || IsKilled;
|
|
|
|
public bool IsAlive { get; set; }
|
|
|
|
float _delayRemaining;
|
|
int _loopsRemaining;
|
|
|
|
public GTween(ITweenBehaviour behaviour)
|
|
{
|
|
Behaviour = behaviour;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts the tween.
|
|
/// </summary>
|
|
/// <param name="isCompletingInstantly">Determines if the tween should complete instantly.</param>
|
|
public void Start(bool isCompletingInstantly = false)
|
|
{
|
|
if (IsPlaying)
|
|
{
|
|
Kill();
|
|
}
|
|
|
|
IsPlaying = true;
|
|
IsCompleted = false;
|
|
IsKilled = false;
|
|
|
|
_delayRemaining = Delay;
|
|
_loopsRemaining = Loops;
|
|
|
|
Behaviour.Start(isCompletingInstantly);
|
|
|
|
OnStartAction?.Invoke();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Advances the tween by a given delta time.
|
|
/// </summary>
|
|
/// <param name="deltaTime">The elapsed time since the last update.</param>
|
|
public void Tick(float deltaTime)
|
|
{
|
|
if (!IsPlaying)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (IsPaused)
|
|
{
|
|
return;
|
|
}
|
|
|
|
float deltaTimeWithTimeScale = TimeScale * deltaTime;
|
|
|
|
if (_delayRemaining > 0f)
|
|
{
|
|
_delayRemaining -= deltaTime;
|
|
return;
|
|
}
|
|
|
|
Behaviour.Tick(deltaTimeWithTimeScale);
|
|
|
|
OnTickAction?.Invoke();
|
|
|
|
bool isFinished = Behaviour.GetFinished();
|
|
|
|
if (!isFinished)
|
|
{
|
|
return;
|
|
}
|
|
|
|
bool needsToLoop = _loopsRemaining > 0 && Behaviour.GetLoopable();
|
|
|
|
if(needsToLoop)
|
|
{
|
|
Loop(LoopResetMode);
|
|
}
|
|
else
|
|
{
|
|
MarkFinished();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets if the tween can continue updating or not. Has effect even if the tween has not startet playing.
|
|
/// If you start a paused tween, it will not update until it's unpaused.
|
|
/// </summary>
|
|
public GTween SetPaused(bool paused)
|
|
{
|
|
IsPaused = paused;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Instantly reaches the final state of the tween, and stops playing.
|
|
/// </summary>
|
|
public void Complete()
|
|
{
|
|
if (!IsPlaying && !IsCompleted)
|
|
{
|
|
Start(true);
|
|
}
|
|
|
|
Behaviour.Complete();
|
|
|
|
_loopsRemaining = 0;
|
|
|
|
MarkFinished();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Kills the tween. This means that the tween will stop playing, leaving it at its current state.
|
|
/// </summary>
|
|
public void Kill()
|
|
{
|
|
if (!IsPlaying)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IsPlaying = false;
|
|
IsCompleted = false;
|
|
IsKilled = true;
|
|
|
|
Behaviour.Kill();
|
|
|
|
OnKillAction?.Invoke();
|
|
OnCompleteOrKillAction?.Invoke();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets the tween, optionally killing it and specifying the reset mode.
|
|
/// </summary>
|
|
/// <param name="kill">Whether to kill the tween.</param>
|
|
/// <param name="resetMode">The reset mode to use.</param>
|
|
/// <returns>The current GTween instance for method chaining.</returns>
|
|
public GTween Reset(bool kill, ResetMode resetMode = ResetMode.InitialValues)
|
|
{
|
|
if (kill)
|
|
{
|
|
Kill();
|
|
IsPlaying = false;
|
|
}
|
|
|
|
IsCompleted = false;
|
|
IsKilled = false;
|
|
|
|
_delayRemaining = Delay;
|
|
|
|
Behaviour.Reset(kill, resetMode);
|
|
|
|
OnResetAction?.Invoke();
|
|
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Simulates the progress of a GTween animation for a specified duration.
|
|
/// </summary>
|
|
/// <param name="time">The simulated time in seconds.</param>
|
|
/// <returns>The current GTween instance for method chaining.</returns>
|
|
public GTween Simulate(float time)
|
|
{
|
|
if (!IsPlaying)
|
|
{
|
|
Start();
|
|
}
|
|
|
|
bool loops = Loops > 0;
|
|
|
|
float simulationTime = loops ?
|
|
time % Behaviour.GetDuration() :
|
|
Math.Min(time, Behaviour.GetDuration());
|
|
|
|
float progress = Behaviour.GetElapsed();
|
|
|
|
while (simulationTime > 0)
|
|
{
|
|
Tick(simulationTime);
|
|
|
|
float newProgress = Behaviour.GetElapsed();
|
|
float tickElapsed = newProgress - progress;
|
|
progress = newProgress;
|
|
|
|
simulationTime -= tickElapsed;
|
|
}
|
|
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds some delay (in seconds) at the begining of the tween.
|
|
/// </summary>
|
|
public GTween SetDelay(float delaySeconds)
|
|
{
|
|
Delay = delaySeconds;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the time scale for the tween, affecting its speed.
|
|
/// By default time scale is 1.0f. If you decrease this number, the tween
|
|
/// will update slower. If you increase it, the tween will update faster.
|
|
/// </summary>
|
|
/// <param name="timeScale">The time scale to set.</param>
|
|
/// <returns>The current GTween instance for method chaining.</returns>
|
|
public GTween SetTimeScale(float timeScale)
|
|
{
|
|
TimeScale = timeScale;
|
|
OnTimeScaleChangedAction?.Invoke(timeScale);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the easing function for the tween.
|
|
/// </summary>
|
|
/// <param name="easingFunction">The custom easing function to use.</param>
|
|
/// <returns>The current GTween instance for method chaining.</returns>
|
|
public GTween SetEasing(EasingDelegate easingFunction)
|
|
{
|
|
Behaviour.SetEasing(easingFunction);
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the predefined easing function for the tween.
|
|
/// </summary>
|
|
/// <param name="easing">The predefined easing to use.</param>
|
|
/// <returns>The current GTween instance for method chaining.</returns>
|
|
public GTween SetEasing(Easing easing)
|
|
{
|
|
return SetEasing(PresetEasingDelegateFactory.GetEaseDelegate(easing));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the number of loops and the reset mode for the tween.
|
|
/// </summary>
|
|
/// <param name="loops">The number of loops.</param>
|
|
/// <param name="resetMode">The reset mode to use when looping.</param>
|
|
/// <returns>The current GTween instance for method chaining.</returns>
|
|
public GTween SetLoops(int loops, ResetMode resetMode = ResetMode.InitialValues)
|
|
{
|
|
Loops = Math.Max(loops, 0);
|
|
LoopResetMode = resetMode;
|
|
return this;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the tween to have and almost infinite amount of loops with the specified reset mode.
|
|
/// </summary>
|
|
/// <param name="resetMode">The reset mode to use when looping.</param>
|
|
/// <returns>The current GTween instance for method chaining.</returns>
|
|
public GTween SetMaxLoops(ResetMode resetMode = ResetMode.InitialValues)
|
|
{
|
|
return SetLoops(int.MaxValue, resetMode);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates the total duration of the tween.
|
|
/// </summary>
|
|
public float GetDuration()
|
|
{
|
|
return Behaviour.GetDuration();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculates the time elapsed since the tween started playing.
|
|
/// </summary>
|
|
public float GetElapsed()
|
|
{
|
|
if(!IsPlaying && !IsCompleted)
|
|
{
|
|
return 0f;
|
|
}
|
|
|
|
if(!IsPlaying && IsCompleted)
|
|
{
|
|
return GetDuration();
|
|
}
|
|
|
|
return Behaviour.GetElapsed();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets the time left remaining on the tween (duration - elapsed).
|
|
/// </summary>
|
|
public float GetRemaining()
|
|
{
|
|
if(!IsPlaying && !IsCompleted)
|
|
{
|
|
return GetDuration();
|
|
}
|
|
|
|
if(!IsPlaying && IsCompleted)
|
|
{
|
|
return 0f;
|
|
}
|
|
|
|
return Behaviour.GetRemaining();
|
|
}
|
|
|
|
public GTween OnStart(Action action)
|
|
{
|
|
OnStartAction += action;
|
|
return this;
|
|
}
|
|
|
|
public GTween OnTick(Action action)
|
|
{
|
|
OnTickAction += action;
|
|
return this;
|
|
}
|
|
|
|
public GTween OnLoop(Action action)
|
|
{
|
|
OnLoopAction += action;
|
|
return this;
|
|
}
|
|
|
|
public GTween OnReset(Action action)
|
|
{
|
|
OnResetAction += action;
|
|
return this;
|
|
}
|
|
|
|
public GTween OnComplete(Action action)
|
|
{
|
|
OnCompleteAction += action;
|
|
return this;
|
|
}
|
|
|
|
public GTween OnKill(Action action)
|
|
{
|
|
OnKillAction += action;
|
|
return this;
|
|
}
|
|
|
|
public GTween OnCompleteOrKill(Action action)
|
|
{
|
|
OnCompleteOrKillAction += action;
|
|
return this;
|
|
}
|
|
|
|
public GTween OnTimeScaleChanged(Action<float> action)
|
|
{
|
|
OnTimeScaleChangedAction += action;
|
|
return this;
|
|
}
|
|
|
|
void Loop(ResetMode loopResetMode)
|
|
{
|
|
bool needsToLoop = _loopsRemaining > 0;
|
|
|
|
if(!needsToLoop || !Behaviour.GetLoopable())
|
|
{
|
|
return;
|
|
}
|
|
|
|
--_loopsRemaining;
|
|
|
|
Reset(kill: false, loopResetMode);
|
|
|
|
IsPlaying = true;
|
|
IsCompleted = false;
|
|
IsKilled = false;
|
|
|
|
Behaviour.Start(false);
|
|
|
|
OnLoopAction?.Invoke();
|
|
}
|
|
|
|
void MarkFinished()
|
|
{
|
|
if (!IsPlaying)
|
|
{
|
|
return;
|
|
}
|
|
|
|
IsPlaying = false;
|
|
IsCompleted = true;
|
|
IsKilled = false;
|
|
|
|
Behaviour.Complete();
|
|
|
|
OnCompleteAction?.Invoke();
|
|
OnCompleteOrKillAction?.Invoke();
|
|
}
|
|
}
|
|
}
|