using System; using System.Collections.Generic; using System.Linq; using UnityEngine.Splines; using UnityEditor.UIElements; using UnityEngine; using UnityEngine.UIElements; namespace UnityEditor.Splines { [CustomEditor(typeof(SplineAnimate))] [CanEditMultipleObjects] class SplineAnimateEditor : UnityEditor.Editor { List m_Roots = new (); List m_ProgressSliders = new (); List m_ElapsedTimeFields = new (); List m_ObjectForwardFields = new (); List m_ObjectUpFields = new (); SerializedProperty m_MethodProperty; SerializedProperty m_ObjectForwardProperty; SerializedProperty m_ObjectUpProperty; SerializedProperty m_StartOffsetProperty; SerializedObject m_TransformSO; SplineAnimate m_SplineAnimate; const string k_UxmlPath = "Packages/com.unity.splines/Editor/Resources/UI/UXML/splineanimate-inspector.uxml"; static VisualTreeAsset s_TreeAsset; static StyleSheet s_ThemeStyleSheet; SplineAnimate[] m_Components; void OnEnable() { m_SplineAnimate = target as SplineAnimate; if (m_SplineAnimate == null) return; m_SplineAnimate.Updated += OnSplineAnimateUpdated; try { m_MethodProperty = serializedObject.FindProperty("m_Method"); m_ObjectForwardProperty = serializedObject.FindProperty("m_ObjectForwardAxis"); m_ObjectUpProperty = serializedObject.FindProperty("m_ObjectUpAxis"); m_StartOffsetProperty = serializedObject.FindProperty("m_StartOffset"); } catch (Exception) { return; } m_TransformSO = new SerializedObject(m_SplineAnimate.transform); m_Components = targets.Select(x => x as SplineAnimate).Where(y => y != null).ToArray(); foreach (var animate in m_Components) { if (animate.Container != null) animate.RecalculateAnimationParameters(); } m_Roots.Clear(); m_ObjectForwardFields.Clear(); m_ObjectUpFields.Clear(); m_ProgressSliders.Clear(); m_ElapsedTimeFields.Clear(); EditorApplication.update += OnEditorUpdate; Spline.Changed += OnSplineChange; SplineContainer.SplineAdded += OnContainerSplineSetModified; SplineContainer.SplineRemoved += OnContainerSplineSetModified; } void OnDisable() { if(m_SplineAnimate != null) m_SplineAnimate.Updated -= OnSplineAnimateUpdated; if (!EditorApplication.isPlaying) { foreach (var animate in m_Components) { if (animate.Container != null) { animate.RecalculateAnimationParameters(); animate.Restart(false); } } } EditorApplication.update -= OnEditorUpdate; Spline.Changed -= OnSplineChange; SplineContainer.SplineAdded -= OnContainerSplineSetModified; SplineContainer.SplineRemoved -= OnContainerSplineSetModified; } void OnEditorUpdate() { if (!EditorApplication.isPlaying) { if (m_SplineAnimate.Container != null && m_SplineAnimate.IsPlaying) { m_SplineAnimate.Update(); RefreshProgressFields(); } } else if(m_SplineAnimate.IsPlaying) RefreshProgressFields(); } void OnSplineChange(Spline spline, int knotIndex, SplineModification modificationType) { if (EditorApplication.isPlayingOrWillChangePlaymode) return; foreach (var animate in m_Components) { if (animate.Container != null && animate.Container.Splines.Contains(spline)) animate.RecalculateAnimationParameters(); } } void OnContainerSplineSetModified(SplineContainer container, int spline) { if (EditorApplication.isPlayingOrWillChangePlaymode) return; foreach (var animate in m_Components) { if (animate.Container == container) animate.RecalculateAnimationParameters(); } } public override VisualElement CreateInspectorGUI() { var root = new VisualElement(); if (s_TreeAsset == null) s_TreeAsset = (VisualTreeAsset)AssetDatabase.LoadAssetAtPath(k_UxmlPath, typeof(VisualTreeAsset)); s_TreeAsset.CloneTree(root); if (s_ThemeStyleSheet == null) s_ThemeStyleSheet = AssetDatabase.LoadAssetAtPath($"Packages/com.unity.splines/Editor/Stylesheets/SplineAnimateInspector{(EditorGUIUtility.isProSkin ? "Dark" : "Light")}.uss"); root.styleSheets.Add(s_ThemeStyleSheet); var methodField = root.Q("method"); methodField.RegisterValueChangeCallback((_) => { RefreshMethodParamFields((SplineAnimate.Method)m_MethodProperty.enumValueIndex); }); RefreshMethodParamFields((SplineAnimate.Method)m_MethodProperty.enumValueIndex); var objectForwardField = root.Q("object-forward"); objectForwardField.RegisterValueChangedCallback((evt) => OnObjectAxisFieldChange(evt, m_ObjectForwardProperty, m_ObjectUpProperty)); var objectUpField = root.Q("object-up"); objectUpField.RegisterValueChangedCallback((evt) => OnObjectAxisFieldChange(evt, m_ObjectUpProperty, m_ObjectForwardProperty)); var playButton = root.Q