PageRenderTime 68ms CodeModel.GetById 34ms app.highlight 29ms RepoModel.GetById 1ms app.codeStats 0ms

/Library/PackageCache/com.unity.timeline@1.2.18/Editor/inspectors/AnimationPlayableAssetInspector.cs

https://gitlab.com/hieplv.amgame/c0lor-blocks
C# | 341 lines | 283 code | 53 blank | 5 comment | 100 complexity | 6cf0dec07e103ac9127ad35e4dbb4d0d MD5 | raw file
  1using System;
  2using System.Linq;
  3using UnityEngine;
  4using UnityEngine.Timeline;
  5
  6namespace UnityEditor.Timeline
  7{
  8    [CustomEditor(typeof(AnimationPlayableAsset)), CanEditMultipleObjects]
  9    class AnimationPlayableAssetInspector : Editor
 10    {
 11        static class Styles
 12        {
 13            public static readonly GUIContent RotationText = EditorGUIUtility.TrTextContent("Rotation");
 14            public static readonly GUIContent AnimClipText = EditorGUIUtility.TrTextContent("Animation Clip");
 15            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");
 16            public static readonly GUIContent AnimationClipName = EditorGUIUtility.TrTextContent("Animation Clip Name");
 17            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.");
 18            public static readonly GUIContent UseDefaults = EditorGUIUtility.TrTextContent("Use defaults");
 19            public static readonly GUIContent RemoveStartOffset = EditorGUIUtility.TrTextContent("Remove Start Offset", "Makes playback of the clip play relative to first key of the root transform");
 20            public static readonly GUIContent ApplyFootIK = EditorGUIUtility.TrTextContent("Foot IK", "Enable to apply foot IK to the AnimationClip when the target is humanoid.");
 21            public static readonly GUIContent Loop = EditorGUIUtility.TrTextContent("Loop", "Whether the source Animation Clip loops during playback.");
 22        }
 23
 24        TimelineWindow m_TimelineWindow;
 25        GameObject m_Binding;
 26
 27        TimelineAnimationUtilities.OffsetEditMode m_OffsetEditMode = TimelineAnimationUtilities.OffsetEditMode.None;
 28        EditorClip m_EditorClip;
 29        EditorClip[] m_EditorClips;
 30
 31        SerializedProperty m_PositionProperty;
 32        SerializedProperty m_RotationProperty;
 33        SerializedProperty m_AnimClipProperty;
 34        SerializedProperty m_UseTrackMatchFieldsProperty;
 35        SerializedProperty m_MatchTargetFieldsProperty;
 36        SerializedObject m_SerializedAnimClip;
 37        SerializedProperty m_SerializedAnimClipName;
 38        SerializedProperty m_RemoveStartOffsetProperty;
 39        SerializedProperty m_ApplyFootIK;
 40        SerializedProperty m_Loop;
 41
 42        Vector3 m_LastPosition;
 43        Vector3 m_LastRotation;
 44
 45        public override void OnInspectorGUI()
 46        {
 47            if (target == null)
 48                return;
 49
 50            serializedObject.Update();
 51
 52            if (!m_TimelineWindow) m_TimelineWindow = TimelineWindow.instance;
 53
 54            ShowAnimationClipField();
 55            ShowRecordableClipRename();
 56            ShowAnimationClipWarnings();
 57
 58            EditorGUI.BeginChangeCheck();
 59
 60            TransformOffsetsGUI();
 61
 62            // extra checks are because the context menu may need to cause a re-evaluate
 63            bool changed = EditorGUI.EndChangeCheck() ||
 64                m_LastPosition != m_PositionProperty.vector3Value ||
 65                m_LastRotation != m_RotationProperty.vector3Value;
 66            m_LastPosition = m_PositionProperty.vector3Value;
 67            m_LastRotation = m_RotationProperty.vector3Value;
 68
 69            if (changed)
 70            {
 71                // updates the changed properties and pushes them to the active playable
 72                serializedObject.ApplyModifiedProperties();
 73                ((AnimationPlayableAsset)target).LiveLink();
 74
 75                // force an evaluate to happen next frame
 76                if (TimelineWindow.instance != null && TimelineWindow.instance.state != null)
 77                {
 78                    TimelineWindow.instance.state.Evaluate();
 79                }
 80            }
 81
 82            EditorGUI.BeginChangeCheck();
 83            EditorGUILayout.PropertyField(m_ApplyFootIK, Styles.ApplyFootIK);
 84            EditorGUILayout.PropertyField(m_Loop, Styles.Loop);
 85            if (EditorGUI.EndChangeCheck())
 86                TimelineEditor.Refresh(RefreshReason.ContentsModified);
 87
 88            serializedObject.ApplyModifiedProperties();
 89        }
 90
 91        void ShowAnimationClipField()
 92        {
 93            bool disabled = m_EditorClips == null || m_EditorClips.Any(c => c.clip == null || c.clip.recordable);
 94            using (new EditorGUI.DisabledScope(disabled))
 95            {
 96                EditorGUI.BeginChangeCheck();
 97                EditorGUILayout.PropertyField(m_AnimClipProperty, Styles.AnimClipText);
 98                if (EditorGUI.EndChangeCheck())
 99                {
100                    // rename the timeline clips to match the animation name if it did previously
101                    if (m_AnimClipProperty.objectReferenceValue != null && m_EditorClips != null)
102                    {
103                        var newName = m_AnimClipProperty.objectReferenceValue.name;
104                        foreach (var c in m_EditorClips)
105                        {
106                            if (c == null || c.clip == null || c.clip.asset == null)
107                                continue;
108
109                            var apa = c.clip.asset as AnimationPlayableAsset;
110                            if (apa != null && apa.clip != null && c.clip.displayName == apa.clip.name)
111                            {
112                                if (c.clip.parentTrack != null)
113                                    Undo.RegisterCompleteObjectUndo(c.clip.parentTrack, "Inspector");
114                                c.clip.displayName = newName;
115                            }
116                        }
117                    }
118
119                    TimelineEditor.Refresh(RefreshReason.ContentsModified);
120                }
121            }
122        }
123
124        void TransformOffsetsMatchFieldsGUI()
125        {
126            var rect = EditorGUILayout.GetControlRect(true);
127            EditorGUI.BeginProperty(rect, Styles.MatchTargetFieldsTitle, m_UseTrackMatchFieldsProperty);
128
129            rect = EditorGUI.PrefixLabel(rect, Styles.MatchTargetFieldsTitle);
130            int oldIndent = EditorGUI.indentLevel;
131            EditorGUI.indentLevel = 0;
132            EditorGUI.BeginChangeCheck();
133            bool val = m_UseTrackMatchFieldsProperty.boolValue;
134            val = EditorGUI.ToggleLeft(rect, Styles.UseDefaults, val);
135            if (EditorGUI.EndChangeCheck())
136                m_UseTrackMatchFieldsProperty.boolValue = val;
137
138            EditorGUI.indentLevel = oldIndent;
139            EditorGUI.EndProperty();
140
141
142            if (!val || m_UseTrackMatchFieldsProperty.hasMultipleDifferentValues)
143            {
144                EditorGUI.indentLevel++;
145                AnimationTrackInspector.MatchTargetsFieldGUI(m_MatchTargetFieldsProperty);
146                EditorGUI.indentLevel--;
147            }
148        }
149
150        void TransformOffsetsGUI()
151        {
152            if (ShouldShowOffsets())
153            {
154                EditorGUILayout.Space();
155                EditorGUILayout.LabelField(Styles.TransformOffsetTitle);
156                EditorGUI.indentLevel++;
157
158                using (new EditorGUI.DisabledScope(targets.Length > 1))
159                {
160                    var previousOffsetMode = m_OffsetEditMode;
161                    AnimationTrackInspector.ShowMotionOffsetEditModeToolbar(ref m_OffsetEditMode);
162                    if (previousOffsetMode != m_OffsetEditMode)
163                    {
164                        SetTimeToClip();
165                        SceneView.RepaintAll();
166                    }
167                }
168
169                EditorGUILayout.BeginHorizontal();
170                EditorGUILayout.PropertyField(m_PositionProperty);
171                EditorGUILayout.EndHorizontal();
172
173                EditorGUILayout.BeginHorizontal();
174                EditorGUILayout.PropertyField(m_RotationProperty, Styles.RotationText);
175                EditorGUILayout.EndHorizontal();
176
177                EditorGUILayout.Space();
178
179                EditorGUI.indentLevel--;
180
181                TransformOffsetsMatchFieldsGUI();
182
183                EditorGUI.BeginChangeCheck();
184                EditorGUILayout.PropertyField(m_RemoveStartOffsetProperty, Styles.RemoveStartOffset);
185                if (EditorGUI.EndChangeCheck())
186                {
187                    TimelineEditor.Refresh(RefreshReason.ContentsAddedOrRemoved);
188                    Repaint();
189                }
190            }
191        }
192
193        void Reevaluate()
194        {
195            if (m_TimelineWindow != null && m_TimelineWindow.state != null)
196            {
197                m_TimelineWindow.state.Refresh();
198                m_TimelineWindow.state.EvaluateImmediate();
199            }
200        }
201
202        // Make sure the director time is within the bounds of the clip
203        void SetTimeToClip()
204        {
205            if (m_TimelineWindow != null && m_TimelineWindow.state != null)
206            {
207                m_TimelineWindow.state.editSequence.time = Math.Min(m_EditorClip.clip.end, Math.Max(m_EditorClip.clip.start, m_TimelineWindow.state.editSequence.time));
208            }
209        }
210
211        public void OnEnable()
212        {
213            if (target == null) // case 946080
214                return;
215
216            m_EditorClip = UnityEditor.Selection.activeObject as EditorClip;
217            m_EditorClips = UnityEditor.Selection.objects.OfType<EditorClip>().ToArray();
218            SceneView.duringSceneGui += OnSceneGUI;
219
220            m_PositionProperty = serializedObject.FindProperty("m_Position");
221            m_PositionProperty.isExpanded = true;
222            m_RotationProperty = serializedObject.FindProperty("m_EulerAngles");
223            m_AnimClipProperty = serializedObject.FindProperty("m_Clip");
224            m_UseTrackMatchFieldsProperty = serializedObject.FindProperty("m_UseTrackMatchFields");
225            m_MatchTargetFieldsProperty = serializedObject.FindProperty("m_MatchTargetFields");
226            m_RemoveStartOffsetProperty = serializedObject.FindProperty("m_RemoveStartOffset");
227            m_ApplyFootIK = serializedObject.FindProperty("m_ApplyFootIK");
228            m_Loop = serializedObject.FindProperty("m_Loop");
229
230            m_LastPosition = m_PositionProperty.vector3Value;
231            m_LastRotation = m_RotationProperty.vector3Value;
232        }
233
234        void OnDestroy()
235        {
236            SceneView.duringSceneGui -= OnSceneGUI;
237        }
238
239        void OnSceneGUI(SceneView sceneView)
240        {
241            DoManipulators();
242        }
243
244        Transform GetTransform()
245        {
246            if (m_Binding != null)
247                return m_Binding.transform;
248
249            if (m_TimelineWindow != null &&  m_TimelineWindow.state != null &&
250                m_TimelineWindow.state.editSequence.director != null &&
251                m_EditorClip != null && m_EditorClip.clip != null)
252            {
253                var obj = TimelineUtility.GetSceneGameObject(m_TimelineWindow.state.editSequence.director,
254                    m_EditorClip.clip.parentTrack);
255                m_Binding = obj;
256                if (obj != null)
257                    return obj.transform;
258            }
259            return null;
260        }
261
262        void DoManipulators()
263        {
264            if (m_EditorClip == null || m_EditorClip.clip == null)
265                return;
266
267            AnimationPlayableAsset animationPlayable = m_EditorClip.clip.asset as AnimationPlayableAsset;
268            AnimationTrack track = m_EditorClip.clip.parentTrack as AnimationTrack;
269            Transform transform = GetTransform();
270
271            if (transform != null && animationPlayable != null && m_OffsetEditMode != TimelineAnimationUtilities.OffsetEditMode.None && track != null)
272            {
273                TimelineUndo.PushUndo(animationPlayable, "Inspector");
274                Vector3 position = transform.position;
275                Quaternion rotation = transform.rotation;
276
277                EditorGUI.BeginChangeCheck();
278                if (m_OffsetEditMode == TimelineAnimationUtilities.OffsetEditMode.Translation)
279                {
280                    position = Handles.PositionHandle(position, Tools.pivotRotation == PivotRotation.Global ? Quaternion.identity : rotation);
281                }
282                else if (m_OffsetEditMode == TimelineAnimationUtilities.OffsetEditMode.Rotation)
283                {
284                    rotation = Handles.RotationHandle(rotation, position);
285                }
286
287                if (EditorGUI.EndChangeCheck())
288                {
289                    var res = TimelineAnimationUtilities.UpdateClipOffsets(animationPlayable, track, transform, position, rotation);
290                    animationPlayable.position = res.position;
291                    animationPlayable.eulerAngles = AnimationUtility.GetClosestEuler(res.rotation, animationPlayable.eulerAngles, RotationOrder.OrderZXY);
292                    Reevaluate();
293                    Repaint();
294                }
295            }
296        }
297
298        void ShowAnimationClipWarnings()
299        {
300            AnimationClip clip = m_AnimClipProperty.objectReferenceValue as AnimationClip;
301            if (clip == null)
302            {
303                EditorGUILayout.HelpBox(AnimationPlayableAssetEditor.k_NoClipAssignedError, MessageType.Warning);
304            }
305            else if (clip.legacy)
306            {
307                EditorGUILayout.HelpBox(AnimationPlayableAssetEditor.k_LegacyClipError, MessageType.Warning);
308            }
309        }
310
311        bool ShouldShowOffsets()
312        {
313            return targets.OfType<AnimationPlayableAsset>().All(x => x.hasRootTransforms);
314        }
315
316        void ShowRecordableClipRename()
317        {
318            if (targets.Length > 1 || m_EditorClip == null || m_EditorClip.clip == null || !m_EditorClip.clip.recordable)
319                return;
320
321            AnimationClip clip = m_AnimClipProperty.objectReferenceValue as AnimationClip;
322            if (clip == null || !AssetDatabase.IsSubAsset(clip))
323                return;
324
325            if (m_SerializedAnimClip == null)
326            {
327                m_SerializedAnimClip = new SerializedObject(clip);
328                m_SerializedAnimClipName = m_SerializedAnimClip.FindProperty("m_Name");
329            }
330
331            if (m_SerializedAnimClipName != null)
332            {
333                m_SerializedAnimClip.Update();
334                EditorGUI.BeginChangeCheck();
335                EditorGUILayout.DelayedTextField(m_SerializedAnimClipName, Styles.AnimationClipName);
336                if (EditorGUI.EndChangeCheck())
337                    m_SerializedAnimClip.ApplyModifiedProperties();
338            }
339        }
340    }
341}