// Animancer // https://kybernetik.com.au/animancer // Copyright 2018-2024 Kybernetik //
using UnityEngine;
namespace Animancer
{
/// An with some additional details (mainly for the Unity Editor GUI).
///
/// Documentation:
///
/// Transitions
///
/// https://kybernetik.com.au/animancer/api/Animancer/ITransitionDetailed
///
public interface ITransitionDetailed : ITransition
{
/************************************************************************************************************************/
/// Can this transition create a valid ?
bool IsValid { get; }
/// What will the value of be for the created state?
bool IsLooping { get; }
/// The to start the animation at.
/// allows the animation to continue from its current time.
float NormalizedStartTime { get; set; }
/// The maximum amount of time the animation is expected to take (in seconds).
/// The actual duration can vary in states like .
float MaximumDuration { get; }
/// The to play the animation at.
float Speed { get; set; }
/************************************************************************************************************************/
}
/// https://kybernetik.com.au/animancer/api/Animancer/AnimancerUtilities
public static partial class AnimancerUtilities
{
/************************************************************************************************************************/
///
/// Is the `transition` not null and ?
///
public static bool IsValid(this ITransitionDetailed transition)
=> transition != null
&& transition.IsValid;
/************************************************************************************************************************/
/// Returns the with support for .
public static bool IsValid(this ITransition transition)
{
if (transition == null)
return false;
if (TryGetWrappedObject(transition, out ITransitionDetailed detailed))
return detailed.IsValid;
return true;
}
/************************************************************************************************************************/
///
/// Returns the
/// or if it's null or throws an exception.
///
public static float TryGetFadeDuration(this ITransition transition)
{
if (transition == null)
return float.NaN;
try
{
return transition.FadeDuration;
}
catch
{
return float.NaN;
}
}
/************************************************************************************************************************/
/// Outputs the or .
/// Returns false if the `motionOrTransition` is null or an unsupported type.
public static bool TryGetIsLooping(object motionOrTransition, out bool isLooping)
{
if (motionOrTransition is Motion motion)
{
if (motion != null)
{
isLooping = motion.isLooping;
return true;
}
}
else if (TryGetWrappedObject(motionOrTransition, out ITransitionDetailed transition))
{
isLooping = transition.IsLooping;
return true;
}
isLooping = false;
return false;
}
/************************************************************************************************************************/
/// Outputs the or .
/// Returns false if the `motionOrTransition` is null or an unsupported type.
public static bool TryGetLength(object motionOrTransition, out float length)
{
if (motionOrTransition is AnimationClip clip)
{
if (clip != null)
{
length = clip.length;
return true;
}
}
else if (TryGetWrappedObject(motionOrTransition, out ITransitionDetailed transition))
{
length = transition.MaximumDuration;
return true;
}
length = 0;
return false;
}
/************************************************************************************************************************/
///
/// Tries to calculate the amount of time (in seconds)
/// from the
/// too the ,
/// including the
///
public static bool TryCalculateDuration(object transition, out float duration)
{
if (!TryGetWrappedObject(transition, out ITransitionDetailed detailed))
{
duration = 0;
return false;
}
var speed = detailed.Speed;
duration = detailed.MaximumDuration;
var normalizedStartTime = detailed.NormalizedStartTime;
if (!float.IsNaN(normalizedStartTime))
duration *= 1 - normalizedStartTime;
if (TryGetWrappedObject(transition, out ITransitionWithEvents events))
{
var normalizedEndTime = events.Events.NormalizedEndTime;
if (!float.IsNaN(normalizedEndTime))
duration *= normalizedEndTime;
}
if (speed.IsFinite() && speed != 0)
duration /= speed;
return true;
}
/************************************************************************************************************************/
}
}