-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Expand file tree
/
Copy pathEmissionModuleUI.cs
More file actions
245 lines (200 loc) · 10.7 KB
/
EmissionModuleUI.cs
File metadata and controls
245 lines (200 loc) · 10.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using UnityEngine;
using UnityEditorInternal;
using System.Collections.Generic;
namespace UnityEditor
{
class EmissionModuleUI : ModuleUI
{
public SerializedMinMaxCurve m_Time;
public SerializedMinMaxCurve m_Distance;
// Keep in sync with EmissionModule.h
const int k_MaxNumBursts = 8;
const float k_BurstDragWidth = 15.0f;
SerializedProperty m_BurstCount;
SerializedProperty m_Bursts;
List<SerializedMinMaxCurve> m_BurstCountCurves = new List<SerializedMinMaxCurve>();
ReorderableList m_BurstList;
class Texts
{
public GUIContent rateOverTime = EditorGUIUtility.TrTextContent("Rate over Time", "The number of particles emitted per second.");
public GUIContent rateOverDistance = EditorGUIUtility.TrTextContent("Rate over Distance", "The number of particles emitted per distance unit.");
public GUIContent burst = EditorGUIUtility.TrTextContent("Bursts", "Emission of extra particles at specific times during the duration of the system.");
public GUIContent burstTime = EditorGUIUtility.TrTextContent("Time", "When the burst will trigger.");
public GUIContent burstCount = EditorGUIUtility.TrTextContent("Count", "The number of particles to emit.");
public GUIContent burstCycleCount = EditorGUIUtility.TrTextContent("Cycles", "How many times to emit the burst. Use the dropdown to repeat infinitely.");
public GUIContent burstCycleCountInfinite = EditorGUIUtility.TrTextContent("Infinite");
public GUIContent burstRepeatInterval = EditorGUIUtility.TrTextContent("Interval", "Repeat the burst every N seconds.");
public GUIContent burstProbability = EditorGUIUtility.TrTextContent("Probability", "0-1 Chance that the burst will trigger.");
}
private static Texts s_Texts;
public EmissionModuleUI(ParticleSystemUI owner, SerializedObject o, string displayName)
: base(owner, o, "EmissionModule", displayName)
{
m_ToolTip = "Emission of the emitter. This controls the rate at which particles are emitted as well as burst emissions.";
}
protected override void Init()
{
// Already initialized?
if (m_BurstCount != null)
return;
if (s_Texts == null)
s_Texts = new Texts();
m_Time = new SerializedMinMaxCurve(this, s_Texts.rateOverTime, "rateOverTime");
m_Distance = new SerializedMinMaxCurve(this, s_Texts.rateOverDistance, "rateOverDistance");
m_BurstCount = GetProperty("m_BurstCount");
m_Bursts = GetProperty("m_Bursts");
m_BurstList = new ReorderableList(serializedObject, m_Bursts, false, true, true, true);
m_BurstList.elementHeight = kReorderableListElementHeight;
m_BurstList.onAddCallback = OnBurstListAddCallback;
m_BurstList.onCanAddCallback = OnBurstListCanAddCallback;
m_BurstList.onRemoveCallback = OnBurstListRemoveCallback;
m_BurstList.drawHeaderCallback = DrawBurstListHeaderCallback;
m_BurstList.drawElementCallback = DrawBurstListElementCallback;
}
override public void OnInspectorGUI(InitialModuleUI initial)
{
GUIMinMaxCurve(s_Texts.rateOverTime, m_Time);
GUIMinMaxCurve(s_Texts.rateOverDistance, m_Distance);
DoBurstGUI(initial);
}
private void DoBurstGUI(InitialModuleUI initial)
{
while (m_BurstList.count > m_BurstCountCurves.Count)
{
SerializedProperty burst = m_Bursts.GetArrayElementAtIndex(m_BurstCountCurves.Count);
m_BurstCountCurves.Add(new SerializedMinMaxCurve(this, s_Texts.burstCount, burst.propertyPath + ".countCurve", false, true));
}
EditorGUILayout.Space();
Rect rect = GetControlRect(kSingleLineHeight);
GUI.Label(rect, s_Texts.burst, ParticleSystemStyles.Get().label);
m_BurstList.displayAdd = (m_Bursts.arraySize < k_MaxNumBursts);
m_BurstList.DoLayoutList();
}
private void OnBurstListAddCallback(ReorderableList list)
{
ReorderableList.defaultBehaviours.DoAddButton(list);
m_BurstCount.intValue++;
SerializedProperty burst = m_Bursts.GetArrayElementAtIndex(list.index);
SerializedProperty burstCountState = burst.FindPropertyRelative("countCurve.minMaxState");
SerializedProperty burstCount = burst.FindPropertyRelative("countCurve.scalar");
SerializedProperty burstCycleCount = burst.FindPropertyRelative("cycleCount");
SerializedProperty burstProbability = burst.FindPropertyRelative("probability");
burstCountState.intValue = (int)ParticleSystemCurveMode.Constant;
burstCount.floatValue = 30.0f;
burstCycleCount.intValue = 1;
burstProbability.floatValue = 1.0f;
SerializedProperty burstCountMinCurve = burst.FindPropertyRelative("countCurve.minCurve");
SerializedProperty burstCountMaxCurve = burst.FindPropertyRelative("countCurve.maxCurve");
burstCountMinCurve.animationCurveValue = AnimationCurve.Linear(0.0f, 1.0f, 1.0f, 1.0f);
burstCountMaxCurve.animationCurveValue = AnimationCurve.Linear(0.0f, 1.0f, 1.0f, 1.0f);
m_BurstCountCurves.Add(new SerializedMinMaxCurve(this, s_Texts.burstCount, burst.propertyPath + ".countCurve", false, true));
}
private bool OnBurstListCanAddCallback(ReorderableList list)
{
return !m_ParticleSystemUI.multiEdit;
}
private void OnBurstListRemoveCallback(ReorderableList list)
{
// All subsequent curves must be removed from the curve editor, as their indices will change, which means their SerializedProperty paths will also change
for (int i = list.index; i < m_BurstCountCurves.Count; i++)
m_BurstCountCurves[i].RemoveCurveFromEditor();
m_BurstCountCurves.RemoveRange(list.index, m_BurstCountCurves.Count - list.index);
AnimationCurvePreviewCache.ClearCache();
// Default remove behavior
ReorderableList.defaultBehaviours.DoRemoveButton(list);
m_BurstCount.intValue--;
}
private void DrawBurstListHeaderCallback(Rect rect)
{
rect.width -= k_BurstDragWidth;
rect.width /= 5;
rect.x += k_BurstDragWidth;
EditorGUI.LabelField(rect, s_Texts.burstTime, ParticleSystemStyles.Get().label);
rect.x += rect.width;
EditorGUI.LabelField(rect, s_Texts.burstCount, ParticleSystemStyles.Get().label);
rect.x += rect.width;
EditorGUI.LabelField(rect, s_Texts.burstCycleCount, ParticleSystemStyles.Get().label);
rect.x += rect.width;
EditorGUI.LabelField(rect, s_Texts.burstRepeatInterval, ParticleSystemStyles.Get().label);
rect.x += rect.width;
EditorGUI.LabelField(rect, s_Texts.burstProbability, ParticleSystemStyles.Get().label);
rect.x += rect.width;
}
private void DrawBurstListElementCallback(Rect rect, int index, bool isActive, bool isFocused)
{
SerializedProperty burst = m_Bursts.GetArrayElementAtIndex(index);
SerializedProperty burstTime = burst.FindPropertyRelative("time");
SerializedProperty burstCycleCount = burst.FindPropertyRelative("cycleCount");
SerializedProperty burstRepeatInterval = burst.FindPropertyRelative("repeatInterval");
SerializedProperty burstProbability = burst.FindPropertyRelative("probability");
rect.width -= (k_BurstDragWidth * 4);
rect.width /= 5;
// Time
FloatDraggable(rect, burstTime, 1.0f, k_BurstDragWidth, "n3");
rect.x += rect.width;
// Count
rect = GUIMinMaxCurveInline(rect, m_BurstCountCurves[index], k_BurstDragWidth);
rect.x += rect.width;
// Cycle Count
rect.width -= k_minMaxToggleWidth;
if (!burstCycleCount.hasMultipleDifferentValues && burstCycleCount.intValue == 0)
{
rect.x += k_BurstDragWidth;
rect.width -= k_BurstDragWidth;
EditorGUI.LabelField(rect, s_Texts.burstCycleCountInfinite, ParticleSystemStyles.Get().label);
}
else
{
IntDraggable(rect, null, burstCycleCount, k_BurstDragWidth);
}
rect.width += k_minMaxToggleWidth;
Rect popupRect = GetPopupRect(rect);
GUIMMModePopUp(popupRect, burstCycleCount);
rect.x += rect.width;
// Repeat Interval
FloatDraggable(rect, burstRepeatInterval, 1.0f, k_BurstDragWidth, "n3");
rect.x += rect.width;
// Probability
FloatDraggable(rect, burstProbability, 1.0f, k_BurstDragWidth, "n2");
rect.x += rect.width;
}
private class ModeCallbackData
{
public ModeCallbackData(int i, SerializedProperty p)
{
modeProp = p;
selectedState = i;
}
public SerializedProperty modeProp;
public int selectedState;
}
private static void SelectModeCallback(object obj)
{
ModeCallbackData data = (ModeCallbackData)obj;
data.modeProp.intValue = (int)data.selectedState;
}
private static void GUIMMModePopUp(Rect rect, SerializedProperty modeProp)
{
if (EditorGUI.DropdownButton(rect, GUIContent.none, FocusType.Passive, ParticleSystemStyles.Get().minMaxCurveStateDropDown))
{
GUIContent[] texts = { EditorGUIUtility.TrTextContent("Infinite"), EditorGUIUtility.TrTextContent("Count") };
GenericMenu menu = new GenericMenu();
for (int i = 0; i < texts.Length; ++i)
{
menu.AddItem(texts[i], (modeProp.intValue == i), SelectModeCallback, new ModeCallbackData(i, modeProp));
}
menu.ShowAsContext();
Event.current.Use();
}
}
override public void UpdateCullingSupportedString(ref string text)
{
Init();
if (m_Distance.scalar.hasMultipleDifferentValues || m_Distance.scalar.floatValue > 0.0f)
text += "\nDistance-based emission is being used in the Emission module.";
}
}
} // namespace UnityEditor