diff options
Diffstat (limited to 'Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs')
| -rw-r--r-- | Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs new file mode 100644 index 0000000..68355c0 --- /dev/null +++ b/Library/PackageCache/com.unity.timeline@1.2.13/Runtime/Animation/AnimationPlayableAsset.cs @@ -0,0 +1,326 @@ +using System.Collections.Generic; +using UnityEngine.Animations; +using UnityEngine.Playables; + +namespace UnityEngine.Timeline +{ + /// <summary> + /// A Playable Asset that represents a single AnimationClip clip. + /// </summary> + [System.Serializable, NotKeyable] + public partial class AnimationPlayableAsset : PlayableAsset, ITimelineClipAsset, IPropertyPreview + { + /// <summary> + /// Whether the source AnimationClip loops during playback. + /// </summary> + public enum LoopMode + { + /// <summary> + /// Use the loop time setting from the source AnimationClip. + /// </summary> + [Tooltip("Use the loop time setting from the source AnimationClip.")] + UseSourceAsset = 0, + + /// <summary> + /// The source AnimationClip loops during playback. + /// </summary> + [Tooltip("The source AnimationClip loops during playback.")] + On = 1, + + /// <summary> + /// The source AnimationClip does not loop during playback. + /// </summary> + [Tooltip("The source AnimationClip does not loop during playback.")] + Off = 2 + } + + + [SerializeField] private AnimationClip m_Clip; + [SerializeField] private Vector3 m_Position = Vector3.zero; + [SerializeField] private Vector3 m_EulerAngles = Vector3.zero; + [SerializeField] private bool m_UseTrackMatchFields = true; + [SerializeField] private MatchTargetFields m_MatchTargetFields = MatchTargetFieldConstants.All; + [SerializeField] private bool m_RemoveStartOffset = true; // set by animation track prior to compilation + [SerializeField] private bool m_ApplyFootIK = true; + [SerializeField] private LoopMode m_Loop = LoopMode.UseSourceAsset; + + +#if UNITY_EDITOR + private AnimationOffsetPlayable m_AnimationOffsetPlayable; +#endif + + /// <summary> + /// The translational offset of the clip + /// </summary> + public Vector3 position + { + get + { + return m_Position; + } + set + { + m_Position = value; +#if UNITY_EDITOR + if (m_AnimationOffsetPlayable.IsValid()) + m_AnimationOffsetPlayable.SetPosition(position); +#endif + } + } + + /// <summary> + /// The rotational offset of the clip, expressed as a Quaternion + /// </summary> + public Quaternion rotation + { + get + { + return Quaternion.Euler(m_EulerAngles); + } + + set + { + m_EulerAngles = value.eulerAngles; +#if UNITY_EDITOR + if (m_AnimationOffsetPlayable.IsValid()) + m_AnimationOffsetPlayable.SetRotation(value); +#endif + } + } + + /// <summary> + /// The rotational offset of the clip, expressed in Euler angles + /// </summary> + public Vector3 eulerAngles + { + get { return m_EulerAngles; } + set + { + m_EulerAngles = value; +#if UNITY_EDITOR + if (m_AnimationOffsetPlayable.IsValid()) + m_AnimationOffsetPlayable.SetRotation(rotation); +#endif + } + } + + /// <summary> + /// Specifies whether to use offset matching options as defined by the track. + /// </summary> + public bool useTrackMatchFields + { + get { return m_UseTrackMatchFields; } + set { m_UseTrackMatchFields = value; } + } + + /// <summary> + /// Specifies which fields should be matched when aligning offsets. + /// </summary> + public MatchTargetFields matchTargetFields + { + get { return m_MatchTargetFields; } + set { m_MatchTargetFields = value; } + } + + /// <summary> + /// Whether to make the animation clip play relative to its first keyframe. + /// </summary> + /// <remarks> + /// This option only applies to animation clips that animate Transform components. + /// </remarks> + public bool removeStartOffset + { + get { return m_RemoveStartOffset; } + set { m_RemoveStartOffset = value; } + } + + + /// <summary> + /// Enable to apply foot IK to the AnimationClip when the target is humanoid. + /// </summary> + public bool applyFootIK + { + get { return m_ApplyFootIK; } + set { m_ApplyFootIK = value; } + } + + /// <summary> + /// Whether the source AnimationClip loops during playback + /// </summary> + public LoopMode loop + { + get { return m_Loop; } + set { m_Loop = value; } + } + + + internal bool hasRootTransforms + { + get { return m_Clip != null && HasRootTransforms(m_Clip); } + } + + // used for legacy 'scene' mode. + internal AppliedOffsetMode appliedOffsetMode { get; set; } + + + /// <summary> + /// The source animation clip + /// </summary> + public AnimationClip clip + { + get { return m_Clip; } + set + { + if (value != null) + name = "AnimationPlayableAsset of " + value.name; + m_Clip = value; + } + } + + /// <summary> + /// Returns the duration required to play the animation clip exactly once + /// </summary> + public override double duration + { + get + { + double length = TimeUtility.GetAnimationClipLength(clip); + if (length < float.Epsilon) + return base.duration; + return length; + } + } + + /// <summary> + /// Returns a description of the PlayableOutputs that may be created for this asset. + /// </summary> + public override IEnumerable<PlayableBinding> outputs + { + get { yield return AnimationPlayableBinding.Create(name, this); } + } + + /// <summary> + /// Creates the root of a Playable subgraph to play the animation clip. + /// </summary> + /// <param name="graph">PlayableGraph that will own the playable</param> + /// <param name="go">The gameobject that triggered the graph build</param> + /// <returns>The root playable of the subgraph</returns> + public override Playable CreatePlayable(PlayableGraph graph, GameObject go) + { + Playable root = CreatePlayable(graph, m_Clip, position, eulerAngles, removeStartOffset, appliedOffsetMode, applyFootIK, m_Loop); + +#if UNITY_EDITOR + m_AnimationOffsetPlayable = AnimationOffsetPlayable.Null; + if (root.IsValid() && root.IsPlayableOfType<AnimationOffsetPlayable>()) + { + m_AnimationOffsetPlayable = (AnimationOffsetPlayable)root; + } + + LiveLink(); +#endif + + return root; + } + + internal static Playable CreatePlayable(PlayableGraph graph, AnimationClip clip, Vector3 positionOffset, Vector3 eulerOffset, bool removeStartOffset, AppliedOffsetMode mode, bool applyFootIK, LoopMode loop) + { + if (clip == null || clip.legacy) + return Playable.Null; + + + var clipPlayable = AnimationClipPlayable.Create(graph, clip); + clipPlayable.SetRemoveStartOffset(removeStartOffset); + clipPlayable.SetApplyFootIK(applyFootIK); + clipPlayable.SetOverrideLoopTime(loop != LoopMode.UseSourceAsset); + clipPlayable.SetLoopTime(loop == LoopMode.On); + + Playable root = clipPlayable; + + if (ShouldApplyScaleRemove(mode)) + { + var removeScale = AnimationRemoveScalePlayable.Create(graph, 1); + graph.Connect(root, 0, removeScale, 0); + removeScale.SetInputWeight(0, 1.0f); + root = removeScale; + } + + if (ShouldApplyOffset(mode, clip)) + { + var offsetPlayable = AnimationOffsetPlayable.Create(graph, positionOffset, Quaternion.Euler(eulerOffset), 1); + graph.Connect(root, 0, offsetPlayable, 0); + offsetPlayable.SetInputWeight(0, 1.0F); + root = offsetPlayable; + } + + return root; + } + + private static bool ShouldApplyOffset(AppliedOffsetMode mode, AnimationClip clip) + { + if (mode == AppliedOffsetMode.NoRootTransform || mode == AppliedOffsetMode.SceneOffsetLegacy) + return false; + + return HasRootTransforms(clip); + } + + private static bool ShouldApplyScaleRemove(AppliedOffsetMode mode) + { + return mode == AppliedOffsetMode.SceneOffsetLegacyEditor || mode == AppliedOffsetMode.SceneOffsetLegacy || mode == AppliedOffsetMode.TransformOffsetLegacy; + } + +#if UNITY_EDITOR + public void LiveLink() + { + if (m_AnimationOffsetPlayable.IsValid()) + { + m_AnimationOffsetPlayable.SetPosition(position); + m_AnimationOffsetPlayable.SetRotation(rotation); + } + } + +#endif + + /// <summary> + /// Returns the capabilities of TimelineClips that contain a AnimationPlayableAsset + /// </summary> + public ClipCaps clipCaps + { + get + { + var caps = ClipCaps.All; + if (m_Clip == null || (m_Loop == LoopMode.Off) || (m_Loop == LoopMode.UseSourceAsset && !m_Clip.isLooping)) + caps &= ~ClipCaps.Looping; + + // empty clips don't support clip in. This allows trim operations to simply become + // move operations + if (m_Clip == null || m_Clip.empty) + caps &= ~ClipCaps.ClipIn; + + return caps; + } + } + + /// <summary> + /// Resets the offsets to default values + /// </summary> + public void ResetOffsets() + { + position = Vector3.zero; + eulerAngles = Vector3.zero; + } + + /// <inheritdoc/> + public void GatherProperties(PlayableDirector director, IPropertyCollector driver) + { + driver.AddFromClip(m_Clip); + } + + internal static bool HasRootTransforms(AnimationClip clip) + { + if (clip == null || clip.empty) + return false; + + return clip.hasRootMotion || clip.hasGenericRootTransform || clip.hasMotionCurves || clip.hasRootCurves; + } + } +} |
