/Library/PackageCache/com.unity.timeline@1.2.18/Editor/inspectors/AnimationPlayableAssetInspector.cs
C# | 341 lines | 283 code | 53 blank | 5 comment | 100 complexity | 6cf0dec07e103ac9127ad35e4dbb4d0d MD5 | raw file
- using System;
- using System.Linq;
- using UnityEngine;
- using UnityEngine.Timeline;
- namespace UnityEditor.Timeline
- {
- [CustomEditor(typeof(AnimationPlayableAsset)), CanEditMultipleObjects]
- class AnimationPlayableAssetInspector : Editor
- {
- static class Styles
- {
- public static readonly GUIContent RotationText = EditorGUIUtility.TrTextContent("Rotation");
- public static readonly GUIContent AnimClipText = EditorGUIUtility.TrTextContent("Animation Clip");
- public static readonly GUIContent TransformOffsetTitle = EditorGUIUtility.TrTextContent("Clip Transform Offsets", "Use this to offset the root transform position and rotation relative to the track when playing this clip");
- public static readonly GUIContent AnimationClipName = EditorGUIUtility.TrTextContent("Animation Clip Name");
- public static readonly GUIContent MatchTargetFieldsTitle = EditorGUIUtility.TrTextContent("Offsets Match Fields", "Fields to apply when matching offsets on clips. The defaults can be set on the track.");
- public static readonly GUIContent UseDefaults = EditorGUIUtility.TrTextContent("Use defaults");
- public static readonly GUIContent RemoveStartOffset = EditorGUIUtility.TrTextContent("Remove Start Offset", "Makes playback of the clip play relative to first key of the root transform");
- public static readonly GUIContent ApplyFootIK = EditorGUIUtility.TrTextContent("Foot IK", "Enable to apply foot IK to the AnimationClip when the target is humanoid.");
- public static readonly GUIContent Loop = EditorGUIUtility.TrTextContent("Loop", "Whether the source Animation Clip loops during playback.");
- }
- TimelineWindow m_TimelineWindow;
- GameObject m_Binding;
- TimelineAnimationUtilities.OffsetEditMode m_OffsetEditMode = TimelineAnimationUtilities.OffsetEditMode.None;
- EditorClip m_EditorClip;
- EditorClip[] m_EditorClips;
- SerializedProperty m_PositionProperty;
- SerializedProperty m_RotationProperty;
- SerializedProperty m_AnimClipProperty;
- SerializedProperty m_UseTrackMatchFieldsProperty;
- SerializedProperty m_MatchTargetFieldsProperty;
- SerializedObject m_SerializedAnimClip;
- SerializedProperty m_SerializedAnimClipName;
- SerializedProperty m_RemoveStartOffsetProperty;
- SerializedProperty m_ApplyFootIK;
- SerializedProperty m_Loop;
- Vector3 m_LastPosition;
- Vector3 m_LastRotation;
- public override void OnInspectorGUI()
- {
- if (target == null)
- return;
- serializedObject.Update();
- if (!m_TimelineWindow) m_TimelineWindow = TimelineWindow.instance;
- ShowAnimationClipField();
- ShowRecordableClipRename();
- ShowAnimationClipWarnings();
- EditorGUI.BeginChangeCheck();
- TransformOffsetsGUI();
- // extra checks are because the context menu may need to cause a re-evaluate
- bool changed = EditorGUI.EndChangeCheck() ||
- m_LastPosition != m_PositionProperty.vector3Value ||
- m_LastRotation != m_RotationProperty.vector3Value;
- m_LastPosition = m_PositionProperty.vector3Value;
- m_LastRotation = m_RotationProperty.vector3Value;
- if (changed)
- {
- // updates the changed properties and pushes them to the active playable
- serializedObject.ApplyModifiedProperties();
- ((AnimationPlayableAsset)target).LiveLink();
- // force an evaluate to happen next frame
- if (TimelineWindow.instance != null && TimelineWindow.instance.state != null)
- {
- TimelineWindow.instance.state.Evaluate();
- }
- }
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.PropertyField(m_ApplyFootIK, Styles.ApplyFootIK);
- EditorGUILayout.PropertyField(m_Loop, Styles.Loop);
- if (EditorGUI.EndChangeCheck())
- TimelineEditor.Refresh(RefreshReason.ContentsModified);
- serializedObject.ApplyModifiedProperties();
- }
- void ShowAnimationClipField()
- {
- bool disabled = m_EditorClips == null || m_EditorClips.Any(c => c.clip == null || c.clip.recordable);
- using (new EditorGUI.DisabledScope(disabled))
- {
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.PropertyField(m_AnimClipProperty, Styles.AnimClipText);
- if (EditorGUI.EndChangeCheck())
- {
- // rename the timeline clips to match the animation name if it did previously
- if (m_AnimClipProperty.objectReferenceValue != null && m_EditorClips != null)
- {
- var newName = m_AnimClipProperty.objectReferenceValue.name;
- foreach (var c in m_EditorClips)
- {
- if (c == null || c.clip == null || c.clip.asset == null)
- continue;
- var apa = c.clip.asset as AnimationPlayableAsset;
- if (apa != null && apa.clip != null && c.clip.displayName == apa.clip.name)
- {
- if (c.clip.parentTrack != null)
- Undo.RegisterCompleteObjectUndo(c.clip.parentTrack, "Inspector");
- c.clip.displayName = newName;
- }
- }
- }
- TimelineEditor.Refresh(RefreshReason.ContentsModified);
- }
- }
- }
- void TransformOffsetsMatchFieldsGUI()
- {
- var rect = EditorGUILayout.GetControlRect(true);
- EditorGUI.BeginProperty(rect, Styles.MatchTargetFieldsTitle, m_UseTrackMatchFieldsProperty);
- rect = EditorGUI.PrefixLabel(rect, Styles.MatchTargetFieldsTitle);
- int oldIndent = EditorGUI.indentLevel;
- EditorGUI.indentLevel = 0;
- EditorGUI.BeginChangeCheck();
- bool val = m_UseTrackMatchFieldsProperty.boolValue;
- val = EditorGUI.ToggleLeft(rect, Styles.UseDefaults, val);
- if (EditorGUI.EndChangeCheck())
- m_UseTrackMatchFieldsProperty.boolValue = val;
- EditorGUI.indentLevel = oldIndent;
- EditorGUI.EndProperty();
- if (!val || m_UseTrackMatchFieldsProperty.hasMultipleDifferentValues)
- {
- EditorGUI.indentLevel++;
- AnimationTrackInspector.MatchTargetsFieldGUI(m_MatchTargetFieldsProperty);
- EditorGUI.indentLevel--;
- }
- }
- void TransformOffsetsGUI()
- {
- if (ShouldShowOffsets())
- {
- EditorGUILayout.Space();
- EditorGUILayout.LabelField(Styles.TransformOffsetTitle);
- EditorGUI.indentLevel++;
- using (new EditorGUI.DisabledScope(targets.Length > 1))
- {
- var previousOffsetMode = m_OffsetEditMode;
- AnimationTrackInspector.ShowMotionOffsetEditModeToolbar(ref m_OffsetEditMode);
- if (previousOffsetMode != m_OffsetEditMode)
- {
- SetTimeToClip();
- SceneView.RepaintAll();
- }
- }
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.PropertyField(m_PositionProperty);
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.BeginHorizontal();
- EditorGUILayout.PropertyField(m_RotationProperty, Styles.RotationText);
- EditorGUILayout.EndHorizontal();
- EditorGUILayout.Space();
- EditorGUI.indentLevel--;
- TransformOffsetsMatchFieldsGUI();
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.PropertyField(m_RemoveStartOffsetProperty, Styles.RemoveStartOffset);
- if (EditorGUI.EndChangeCheck())
- {
- TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
- Repaint();
- }
- }
- }
- void Reevaluate()
- {
- if (m_TimelineWindow != null && m_TimelineWindow.state != null)
- {
- m_TimelineWindow.state.Refresh();
- m_TimelineWindow.state.EvaluateImmediate();
- }
- }
- // Make sure the director time is within the bounds of the clip
- void SetTimeToClip()
- {
- if (m_TimelineWindow != null && m_TimelineWindow.state != null)
- {
- m_TimelineWindow.state.editSequence.time = Math.Min(m_EditorClip.clip.end, Math.Max(m_EditorClip.clip.start, m_TimelineWindow.state.editSequence.time));
- }
- }
- public void OnEnable()
- {
- if (target == null) // case 946080
- return;
- m_EditorClip = UnityEditor.Selection.activeObject as EditorClip;
- m_EditorClips = UnityEditor.Selection.objects.OfType<EditorClip>().ToArray();
- SceneView.duringSceneGui += OnSceneGUI;
- m_PositionProperty = serializedObject.FindProperty("m_Position");
- m_PositionProperty.isExpanded = true;
- m_RotationProperty = serializedObject.FindProperty("m_EulerAngles");
- m_AnimClipProperty = serializedObject.FindProperty("m_Clip");
- m_UseTrackMatchFieldsProperty = serializedObject.FindProperty("m_UseTrackMatchFields");
- m_MatchTargetFieldsProperty = serializedObject.FindProperty("m_MatchTargetFields");
- m_RemoveStartOffsetProperty = serializedObject.FindProperty("m_RemoveStartOffset");
- m_ApplyFootIK = serializedObject.FindProperty("m_ApplyFootIK");
- m_Loop = serializedObject.FindProperty("m_Loop");
- m_LastPosition = m_PositionProperty.vector3Value;
- m_LastRotation = m_RotationProperty.vector3Value;
- }
- void OnDestroy()
- {
- SceneView.duringSceneGui -= OnSceneGUI;
- }
- void OnSceneGUI(SceneView sceneView)
- {
- DoManipulators();
- }
- Transform GetTransform()
- {
- if (m_Binding != null)
- return m_Binding.transform;
- if (m_TimelineWindow != null && m_TimelineWindow.state != null &&
- m_TimelineWindow.state.editSequence.director != null &&
- m_EditorClip != null && m_EditorClip.clip != null)
- {
- var obj = TimelineUtility.GetSceneGameObject(m_TimelineWindow.state.editSequence.director,
- m_EditorClip.clip.parentTrack);
- m_Binding = obj;
- if (obj != null)
- return obj.transform;
- }
- return null;
- }
- void DoManipulators()
- {
- if (m_EditorClip == null || m_EditorClip.clip == null)
- return;
- AnimationPlayableAsset animationPlayable = m_EditorClip.clip.asset as AnimationPlayableAsset;
- AnimationTrack track = m_EditorClip.clip.parentTrack as AnimationTrack;
- Transform transform = GetTransform();
- if (transform != null && animationPlayable != null && m_OffsetEditMode != TimelineAnimationUtilities.OffsetEditMode.None && track != null)
- {
- TimelineUndo.PushUndo(animationPlayable, "Inspector");
- Vector3 position = transform.position;
- Quaternion rotation = transform.rotation;
- EditorGUI.BeginChangeCheck();
- if (m_OffsetEditMode == TimelineAnimationUtilities.OffsetEditMode.Translation)
- {
- position = Handles.PositionHandle(position, Tools.pivotRotation == PivotRotation.Global ? Quaternion.identity : rotation);
- }
- else if (m_OffsetEditMode == TimelineAnimationUtilities.OffsetEditMode.Rotation)
- {
- rotation = Handles.RotationHandle(rotation, position);
- }
- if (EditorGUI.EndChangeCheck())
- {
- var res = TimelineAnimationUtilities.UpdateClipOffsets(animationPlayable, track, transform, position, rotation);
- animationPlayable.position = res.position;
- animationPlayable.eulerAngles = AnimationUtility.GetClosestEuler(res.rotation, animationPlayable.eulerAngles, RotationOrder.OrderZXY);
- Reevaluate();
- Repaint();
- }
- }
- }
- void ShowAnimationClipWarnings()
- {
- AnimationClip clip = m_AnimClipProperty.objectReferenceValue as AnimationClip;
- if (clip == null)
- {
- EditorGUILayout.HelpBox(AnimationPlayableAssetEditor.k_NoClipAssignedError, MessageType.Warning);
- }
- else if (clip.legacy)
- {
- EditorGUILayout.HelpBox(AnimationPlayableAssetEditor.k_LegacyClipError, MessageType.Warning);
- }
- }
- bool ShouldShowOffsets()
- {
- return targets.OfType<AnimationPlayableAsset>().All(x => x.hasRootTransforms);
- }
- void ShowRecordableClipRename()
- {
- if (targets.Length > 1 || m_EditorClip == null || m_EditorClip.clip == null || !m_EditorClip.clip.recordable)
- return;
- AnimationClip clip = m_AnimClipProperty.objectReferenceValue as AnimationClip;
- if (clip == null || !AssetDatabase.IsSubAsset(clip))
- return;
- if (m_SerializedAnimClip == null)
- {
- m_SerializedAnimClip = new SerializedObject(clip);
- m_SerializedAnimClipName = m_SerializedAnimClip.FindProperty("m_Name");
- }
- if (m_SerializedAnimClipName != null)
- {
- m_SerializedAnimClip.Update();
- EditorGUI.BeginChangeCheck();
- EditorGUILayout.DelayedTextField(m_SerializedAnimClipName, Styles.AnimationClipName);
- if (EditorGUI.EndChangeCheck())
- m_SerializedAnimClip.ApplyModifiedProperties();
- }
- }
- }
- }