// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2023 Kybernetik //
using System.Collections.Generic;
using UnityEngine;
namespace Animancer
{
/// A system for synchronizing the of certain animations.
///
///
/// - Initialize a
by adding any objects you want to synchronize.
/// - Call any of the
methods before playing a new animation.
/// - Call any of the
methods after playing that animation.
///
/// Example: Character Controller -> Synchronization
///
/// https://kybernetik.com.au/animancer/api/Animancer/TimeSynchronizationGroup
///
public class TimeSynchronizationGroup : HashSet
{
/************************************************************************************************************************/
private AnimancerComponent _Animancer;
/// The this group is synchronizing.
///
/// This reference is not required if you always use the store and sync methods that take an
/// .
///
public AnimancerComponent Animancer
{
get => _Animancer;
set
{
_Animancer = value;
NormalizedTime = null;
}
}
/************************************************************************************************************************/
/// The stored or null if no value was stored.
public float? NormalizedTime { get; set; }
/************************************************************************************************************************/
/// Creates a new and sets its .
public TimeSynchronizationGroup(AnimancerComponent animancer) => Animancer = animancer;
/************************************************************************************************************************/
///
/// Stores the of the 's current state if
/// the `key` is in this group.
///
public bool StoreTime(object key) => StoreTime(key, Animancer.States.Current);
///
/// Stores the of the `state` if the `key` is in this group.
///
public bool StoreTime(object key, AnimancerState state)
{
if (state != null && Contains(key))
{
NormalizedTime = state.NormalizedTime;
return true;
}
else
{
NormalizedTime = null;
return false;
}
}
/************************************************************************************************************************/
///
/// Applies the to the 's current state if the `key` is in
/// this group.
///
public bool SyncTime(object key) => SyncTime(key, Time.deltaTime);
///
/// Applies the to the 's current state if the `key` is in
/// this group.
///
public bool SyncTime(object key, float deltaTime) => SyncTime(key, Animancer.States.Current, deltaTime);
/// Applies the to the `state` if the `key` is in this group.
public bool SyncTime(object key, AnimancerState state) => SyncTime(key, state, Time.deltaTime);
/// Applies the to the `state` if the `key` is in this group.
public bool SyncTime(object key, AnimancerState state, float deltaTime)
{
if (NormalizedTime == null ||
state == null ||
!Contains(key))
return false;
// Setting the Time forces it to stay at that value after the next animation update.
// But we actually want it to keep playing, so we need to add deltaTime manually.
state.Time = NormalizedTime.Value * state.Length + deltaTime * state.EffectiveSpeed;
return true;
}
/************************************************************************************************************************/
}
}