Skip to content

Commit e17b4a0

Browse files
committed
feat: UIEffectTweener animation preview in edit mode
close #279
1 parent 1558736 commit e17b4a0

File tree

1 file changed

+92
-59
lines changed

1 file changed

+92
-59
lines changed
+92-59
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
using UnityEditor;
1+
using System.Linq;
2+
using UnityEditor;
23
using UnityEngine;
34
using UnityEngine.Profiling;
45

56
namespace Coffee.UIEffects.Editors
67
{
78
[CanEditMultipleObjects]
89
[CustomEditor(typeof(UIEffectTweener))]
9-
internal class UIMaterialPropertyTweenerEditor : Editor
10+
internal class UIEffectTweenerEditor : Editor
1011
{
1112
private SerializedProperty _cullingMask;
1213
private SerializedProperty _direction;
@@ -17,6 +18,8 @@ internal class UIMaterialPropertyTweenerEditor : Editor
1718
private SerializedProperty _playOnEnable;
1819
private SerializedProperty _updateMode;
1920
private SerializedProperty _wrapMode;
21+
private bool _isPlaying = false;
22+
private double _lastTime;
2023

2124
private void OnEnable()
2225
{
@@ -29,11 +32,18 @@ private void OnEnable()
2932
_interval = serializedObject.FindProperty("m_Interval");
3033
_wrapMode = serializedObject.FindProperty("m_WrapMode");
3134
_updateMode = serializedObject.FindProperty("m_UpdateMode");
35+
36+
EditorApplication.update += UpdateTweeners;
37+
}
38+
39+
private void OnDisable()
40+
{
41+
EditorApplication.update -= UpdateTweeners;
3242
}
3343

3444
public override void OnInspectorGUI()
3545
{
36-
Profiler.BeginSample("(MPI)[MPTweenerEditor] OnInspectorGUI");
46+
Profiler.BeginSample("(UIE)[UIEffectTweener] OnInspectorGUI");
3747
serializedObject.UpdateIfRequiredOrScript();
3848
EditorGUILayout.PropertyField(_cullingMask);
3949
EditorGUILayout.PropertyField(_direction);
@@ -53,74 +63,62 @@ private void DrawPlayer(UIEffectTweener tweener)
5363
{
5464
if (!tweener) return;
5565

66+
EditorGUILayout.Space(4);
67+
GUILayout.Label(GUIContent.none, "sv_iconselector_sep", GUILayout.ExpandWidth(true));
68+
5669
EditorGUILayout.BeginHorizontal();
57-
EditorGUI.BeginDisabledGroup(!Application.isPlaying);
58-
var icon = EditorGUIUtility.IconContent("icons/playbutton.png");
5970
var r = EditorGUILayout.GetControlRect(false);
71+
var rResetTimeButton = new Rect(r.x, r.y, 20, r.height);
72+
if (GUI.Button(rResetTimeButton, EditorGUIUtility.IconContent("animation.firstkey"), "IconButton"))
73+
{
74+
SetTime(0);
75+
}
6076

61-
var rButton = new Rect(r.x, r.y, 20, r.height);
62-
if (GUI.Button(rButton, icon, "IconButton"))
77+
var rPlayButton = new Rect(r.x + 20, r.y, 20, r.height);
78+
if (GUI.Button(rPlayButton, EditorGUIUtility.IconContent("playbutton"), "IconButton"))
6379
{
64-
tweener.SetTime(0);
80+
SetPlaying(true);
6581
}
6682

67-
EditorGUI.EndDisabledGroup();
83+
var rPauseButton = new Rect(r.x + 40, r.y, 20, r.height);
84+
if (GUI.Button(rPauseButton, EditorGUIUtility.IconContent("pausebutton"), "IconButton"))
85+
{
86+
SetPlaying(false);
87+
}
6888

6989
var totalTime = tweener.totalTime;
7090
var time = tweener.time;
7191
var label = EditorGUIUtility.TrTempContent($"{time:N2}/{totalTime:N2}");
72-
var wLabel = Mathf.CeilToInt(EditorStyles.label.CalcSize(label).x / 5f) * 5f;
73-
wLabel = 80;
74-
var rLabel = new Rect(r.x + r.width - wLabel, r.y, wLabel, r.height);
92+
var rLabel = new Rect(r.x + r.width - 80, r.y, 80, r.height);
7593
GUI.Label(rLabel, label, "RightLabel");
7694
EditorGUILayout.EndHorizontal();
7795

7896
EditorGUI.BeginChangeCheck();
79-
var rSlider = new Rect(r.x + 20, r.y, r.width - wLabel - 20, r.height);
80-
81-
//
97+
var rSlider = new Rect(r.x + 60, r.y, r.width - 140, r.height);
98+
var r0 = new Rect(rSlider.x, rSlider.y + 4, rSlider.width, rSlider.height - 8);
99+
r0.x += DrawBackground(r0, rSlider.width * tweener.delay / totalTime, Color.blue);
100+
r0.x += DrawBackground(r0, rSlider.width * tweener.duration / totalTime, Color.green);
82101

83-
var
84-
r0 = rSlider; //new Rect(rSlider.x, rSlider.y, rSlider.width * tweener.interval / totalTime, rSlider.height);
85-
r0.y += 4;
86-
r0.height -= 8;
87-
r0.width = rSlider.width * tweener.delay / totalTime;
88-
GUI.color = Color.blue;
89-
GUI.Label(r0, GUIContent.none, "TE DefaultTime");
90-
91-
r0.x += r0.width;
92-
r0.width = rSlider.width * tweener.duration / totalTime;
93-
GUI.color = Color.green;
94-
GUI.Label(r0, GUIContent.none, "TE DefaultTime");
95-
96-
r0.x += r0.width;
97-
r0.width = rSlider.width * tweener.interval / totalTime;
98-
GUI.color = Color.red;
99-
GUI.Label(r0, GUIContent.none, "TE DefaultTime");
102+
if (UIEffectTweener.WrapMode.Loop <= tweener.wrapMode)
103+
{
104+
r0.x += DrawBackground(r0, rSlider.width * tweener.interval / totalTime, Color.red);
105+
}
100106

101107
if (UIEffectTweener.WrapMode.PingPongOnce <= tweener.wrapMode)
102108
{
103-
r0.x += r0.width;
104-
r0.width = rSlider.width * tweener.duration / totalTime;
105-
GUI.color = Color.green;
106-
GUI.Label(r0, GUIContent.none, "TE DefaultTime");
109+
r0.x += DrawBackground(r0, rSlider.width * tweener.duration / totalTime, Color.green);
107110
}
108111

109112
if (UIEffectTweener.WrapMode.PingPongLoop <= tweener.wrapMode)
110113
{
111-
r0.x += r0.width;
112-
r0.width = rSlider.width * tweener.interval / totalTime;
113-
GUI.color = Color.red;
114-
GUI.Label(r0, GUIContent.none, "TE DefaultTime");
114+
r0.x += DrawBackground(r0, rSlider.width * tweener.interval / totalTime, Color.red);
115115
}
116116

117-
118117
GUI.color = Color.white;
119-
120118
time = GUI.HorizontalSlider(rSlider, time, 0, totalTime);
121119
if (EditorGUI.EndChangeCheck())
122120
{
123-
tweener.SetTime(time);
121+
SetTime(time);
124122
}
125123

126124
if (Application.isPlaying && tweener.isActiveAndEnabled)
@@ -129,21 +127,56 @@ private void DrawPlayer(UIEffectTweener tweener)
129127
}
130128
}
131129

132-
// private static void PostAddElement(SerializedProperty prop, string propertyName)
133-
// {
134-
// prop.FindPropertyRelative("m_From.m_Type").intValue = -1;
135-
// prop.FindPropertyRelative("m_From.m_PropertyName").stringValue = propertyName;
136-
// prop.FindPropertyRelative("m_To.m_Type").intValue = -1;
137-
// prop.FindPropertyRelative("m_To.m_PropertyName").stringValue = propertyName;
138-
// }
139-
//
140-
// private void ResetCallback()
141-
// {
142-
// var current = serializedObject.targetObject as UIEffectTweener;
143-
// if (!current) return;
144-
//
145-
// Undo.RecordObject(current, "Reset Values");
146-
// current.ResetPropertiesToDefault();
147-
// }
130+
private static float DrawBackground(Rect r, float width, Color color)
131+
{
132+
r.width = width;
133+
GUI.color = color;
134+
GUI.Label(r, GUIContent.none, "TE DefaultTime");
135+
return width;
136+
}
137+
138+
private void SetTime(float time)
139+
{
140+
foreach (var tweener in targets.OfType<UIEffectTweener>())
141+
{
142+
tweener.SetTime(time);
143+
}
144+
}
145+
146+
private void SetPlaying(bool enable)
147+
{
148+
if (!EditorApplication.isPlaying)
149+
{
150+
_isPlaying = enable;
151+
_lastTime = EditorApplication.timeSinceStartup;
152+
return;
153+
}
154+
155+
foreach (var tweener in targets.OfType<UIEffectTweener>())
156+
{
157+
if (enable)
158+
{
159+
tweener.Play(false);
160+
}
161+
else
162+
{
163+
tweener.SetPause(true);
164+
}
165+
}
166+
}
167+
168+
private void UpdateTweeners()
169+
{
170+
if (!_isPlaying || EditorApplication.isPlayingOrWillChangePlaymode) return;
171+
172+
var delta = (float)(EditorApplication.timeSinceStartup - _lastTime);
173+
_lastTime = EditorApplication.timeSinceStartup;
174+
foreach (var tweener in targets.OfType<UIEffectTweener>())
175+
{
176+
tweener.UpdateTime(tweener.direction == UIEffectTweener.Direction.Forward ? delta : -delta);
177+
}
178+
179+
EditorApplication.QueuePlayerLoopUpdate();
180+
}
148181
}
149182
}

0 commit comments

Comments
 (0)