PageRenderTime 30ms CodeModel.GetById 0ms RepoModel.GetById 0ms app.codeStats 1ms

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