// 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; } /************************************************************************************************************************/ } }