forked from Unity-Technologies/UnityCsReference
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTriggerModuleUI.cs
More file actions
231 lines (196 loc) · 10.4 KB
/
Copy pathTriggerModuleUI.cs
File metadata and controls
231 lines (196 loc) · 10.4 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
// 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 System.Collections.Generic;
namespace UnityEditor
{
class TriggerModuleUI : ModuleUI
{
// Keep in sync with TriggerModule.h
const int k_MaxNumCollisionShapes = 6;
enum OverlapOptions { Ignore = 0, Kill = 1, Callback = 2 };
SerializedProperty[] m_CollisionShapes = new SerializedProperty[k_MaxNumCollisionShapes];
SerializedProperty m_Inside;
SerializedProperty m_Outside;
SerializedProperty m_Enter;
SerializedProperty m_Exit;
SerializedProperty m_RadiusScale;
SerializedProperty[] m_ShownCollisionShapes;
static bool s_VisualizeBounds = false;
class Texts
{
public GUIContent collisionShapes = EditorGUIUtility.TrTextContent("Colliders", "The list of collision shapes to use for the trigger.");
public GUIContent createCollisionShape = EditorGUIUtility.TrTextContent("", "Create a GameObject containing a sphere collider and assigns it to the list.");
public GUIContent inside = EditorGUIUtility.TrTextContent("Inside", "What to do for particles that are inside the collision volume.");
public GUIContent outside = EditorGUIUtility.TrTextContent("Outside", "What to do for particles that are outside the collision volume.");
public GUIContent enter = EditorGUIUtility.TrTextContent("Enter", "Triggered once when particles enter the collison volume.");
public GUIContent exit = EditorGUIUtility.TrTextContent("Exit", "Triggered once when particles leave the collison volume.");
public GUIContent radiusScale = EditorGUIUtility.TrTextContent("Radius Scale", "Scale particle bounds by this amount to get more precise collisions.");
public GUIContent visualizeBounds = EditorGUIUtility.TrTextContent("Visualize Bounds", "Render the collision bounds of the particles.");
public GUIContent[] overlapOptions = new GUIContent[]
{
EditorGUIUtility.TrTextContent("Ignore"),
EditorGUIUtility.TrTextContent("Kill"),
EditorGUIUtility.TrTextContent("Callback")
};
}
private static Texts s_Texts;
public TriggerModuleUI(ParticleSystemUI owner, SerializedObject o, string displayName)
: base(owner, o, "TriggerModule", displayName)
{
m_ToolTip = "Allows you to execute script code based on whether particles are inside or outside the collision shapes.";
}
protected override void Init()
{
// Already initialized?
if (m_Inside != null)
return;
if (s_Texts == null)
s_Texts = new Texts();
List<SerializedProperty> shownCollisionShapes = new List<SerializedProperty>();
for (int i = 0; i < m_CollisionShapes.Length; ++i)
{
m_CollisionShapes[i] = GetProperty("collisionShape" + i); // Keep name in sync with transfer func in TriggerModule.h
System.Diagnostics.Debug.Assert(m_CollisionShapes[i] != null);
// Always show the first collision shape
if (i == 0 || m_CollisionShapes[i].objectReferenceValue != null)
shownCollisionShapes.Add(m_CollisionShapes[i]);
}
m_ShownCollisionShapes = shownCollisionShapes.ToArray();
m_Inside = GetProperty("inside");
m_Outside = GetProperty("outside");
m_Enter = GetProperty("enter");
m_Exit = GetProperty("exit");
m_RadiusScale = GetProperty("radiusScale");
s_VisualizeBounds = EditorPrefs.GetBool("VisualizeTriggerBounds", false);
}
override public void OnInspectorGUI(InitialModuleUI initial)
{
DoListOfCollisionShapesGUI();
GUIPopup(s_Texts.inside, m_Inside, s_Texts.overlapOptions);
GUIPopup(s_Texts.outside, m_Outside, s_Texts.overlapOptions);
GUIPopup(s_Texts.enter, m_Enter, s_Texts.overlapOptions);
GUIPopup(s_Texts.exit, m_Exit, s_Texts.overlapOptions);
GUIFloat(s_Texts.radiusScale, m_RadiusScale);
EditorGUI.BeginChangeCheck();
s_VisualizeBounds = GUIToggle(s_Texts.visualizeBounds, s_VisualizeBounds);
if (EditorGUI.EndChangeCheck())
{
EditorPrefs.SetBool("VisualizeTriggerBounds", s_VisualizeBounds);
}
}
private static GameObject CreateDefaultCollider(string name, ParticleSystem parentOfGameObject)
{
GameObject go = new GameObject(name);
if (go)
{
if (parentOfGameObject)
go.transform.parent = parentOfGameObject.transform;
go.AddComponent<SphereCollider>();
return go;
}
return null;
}
private void DoListOfCollisionShapesGUI()
{
// only show the list of colliders when we can edit them safely
if (m_ParticleSystemUI.multiEdit)
{
for (int shapeIndex = 0; shapeIndex < k_MaxNumCollisionShapes; shapeIndex++)
{
int hasShape = -1;
foreach (ParticleSystem ps in m_ParticleSystemUI.m_ParticleSystems)
{
int shapeValue = (ps.trigger.GetCollider(shapeIndex) != null) ? 1 : 0;
if (hasShape == -1)
{
hasShape = shapeValue;
}
else if (shapeValue != hasShape)
{
EditorGUILayout.HelpBox("Collider list editing is only available when all selected systems contain the same number of colliders", MessageType.Info, true);
return;
}
}
}
}
int buttonPressedIndex = GUIListOfFloatObjectToggleFields(s_Texts.collisionShapes, m_ShownCollisionShapes, null, s_Texts.createCollisionShape, !m_ParticleSystemUI.multiEdit);
if (buttonPressedIndex >= 0 && !m_ParticleSystemUI.multiEdit)
{
GameObject go = CreateDefaultCollider("Collider " + (buttonPressedIndex + 1), m_ParticleSystemUI.m_ParticleSystems[0]);
go.transform.localPosition = new Vector3(0, 0, 10 + buttonPressedIndex); // ensure each collider is not at same pos
m_ShownCollisionShapes[buttonPressedIndex].objectReferenceValue = go;
}
// Minus button
Rect rect = GUILayoutUtility.GetRect(0, EditorGUI.kSingleLineHeight); //GUILayoutUtility.GetLastRect();
rect.x = rect.xMax - kPlusAddRemoveButtonWidth * 2 - kPlusAddRemoveButtonSpacing;
rect.width = kPlusAddRemoveButtonWidth;
if (m_ShownCollisionShapes.Length > 1)
{
if (MinusButton(rect))
{
m_ShownCollisionShapes[m_ShownCollisionShapes.Length - 1].objectReferenceValue = null;
List<SerializedProperty> shownCollisionShapes = new List<SerializedProperty>(m_ShownCollisionShapes);
shownCollisionShapes.RemoveAt(shownCollisionShapes.Count - 1);
m_ShownCollisionShapes = shownCollisionShapes.ToArray();
}
}
// Plus button
if (m_ShownCollisionShapes.Length < k_MaxNumCollisionShapes && !m_ParticleSystemUI.multiEdit)
{
rect.x += kPlusAddRemoveButtonWidth + kPlusAddRemoveButtonSpacing;
if (PlusButton(rect))
{
List<SerializedProperty> shownCollisionShapes = new List<SerializedProperty>(m_ShownCollisionShapes);
shownCollisionShapes.Add(m_CollisionShapes[shownCollisionShapes.Count]);
m_ShownCollisionShapes = shownCollisionShapes.ToArray();
}
}
}
override public void OnSceneViewGUI()
{
if (s_VisualizeBounds == false)
return;
Color oldColor = Handles.color;
Handles.color = Color.green;
Matrix4x4 oldMatrix = Handles.matrix;
Vector3[] points0 = new Vector3[20];
Vector3[] points1 = new Vector3[20];
Vector3[] points2 = new Vector3[20];
Handles.SetDiscSectionPoints(points0, Vector3.zero, Vector3.forward, Vector3.right, 360, 1.0f);
Handles.SetDiscSectionPoints(points1, Vector3.zero, Vector3.up, -Vector3.right, 360, 1.0f);
Handles.SetDiscSectionPoints(points2, Vector3.zero, Vector3.right, Vector3.up, 360, 1.0f);
Vector3[] points = new Vector3[points0.Length + points1.Length + points2.Length];
points0.CopyTo(points, 0);
points1.CopyTo(points, 20);
points2.CopyTo(points, 40);
foreach (ParticleSystem ps in m_ParticleSystemUI.m_ParticleSystems)
{
if (!ps.trigger.enabled)
continue;
ParticleSystem.Particle[] particles = new ParticleSystem.Particle[ps.particleCount];
int count = ps.GetParticles(particles);
Matrix4x4 transform = Matrix4x4.identity;
if (ps.main.simulationSpace == ParticleSystemSimulationSpace.Local)
{
transform = ps.GetLocalToWorldMatrix();
}
for (int i = 0; i < count; i++)
{
ParticleSystem.Particle particle = particles[i];
Vector3 size = particle.GetCurrentSize3D(ps);
float radius = System.Math.Max(size.x, System.Math.Max(size.y, size.z)) * 0.5f * ps.trigger.radiusScale;
Handles.matrix = transform * Matrix4x4.TRS(particle.position, Quaternion.identity, new Vector3(radius, radius, radius));
Handles.DrawPolyLine(points);
}
}
Handles.color = oldColor;
Handles.matrix = oldMatrix;
}
public override void UpdateCullingSupportedString(ref string text)
{
text += "\nTriggers module is enabled.";
}
}
} // namespace UnityEditor