Skip to content

Commit 8394ec2

Browse files
committed
Finalized the scene selector.
1 parent b11ae04 commit 8394ec2

4 files changed

Lines changed: 212 additions & 38 deletions

File tree

Assets/Editor Toolbox/Editor/SceneView/ToolboxEditorSceneViewObjectSelector.cs

Lines changed: 198 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,21 @@ public class ToolboxEditorSceneViewObjectSelector : EditorWindow
99
private List<GameObject> gameObjects;
1010
private List<string> gameObjectPaths;
1111

12-
private const float sizeXPadding = 8f;
13-
private const float sizeYPadding = 4f;
14-
private const float sizeYspacing = 2.0f;
12+
private const float sizeXPadding = 2f;
13+
private const float sizeYPadding = 2f;
14+
private const float buttonYSpacing = 0.0f;
15+
private const float buttonYSize = 20f;
16+
private const float sizeXOffset = -30f;
1517

1618
private GameObject highlightedObject;
1719
private Vector2 size;
20+
private Vector2 buttonSize;
1821
private GUIStyle buttonStyle;
22+
private Color selectionColor = new Color(0.50f, 0.70f, 1.00f);
23+
24+
private int shiftMinSelectionID = -1;
25+
private int shiftMaxSelectionID = -1;
26+
private int shiftLastID = -1;
1927

2028
private GameObject HighlightedObject
2129
{
@@ -27,8 +35,12 @@ private GameObject HighlightedObject
2735
}
2836

2937
highlightedObject = value;
30-
Selection.activeGameObject = value;
3138
UnityEditor.SceneView.RepaintAll();
39+
40+
if (highlightedObject != null)
41+
{
42+
EditorGUIUtility.PingObject(highlightedObject);
43+
}
3244
}
3345
}
3446

@@ -58,24 +70,26 @@ private Vector2 CalculateSize()
5870
InitializeStyle();
5971
}
6072

61-
GUIContent content = new GUIContent();
62-
6373
size = Vector2.zero;
6474

65-
foreach (string path in gameObjectPaths)
75+
foreach (GameObject go in gameObjects)
6676
{
67-
content.text = path;
77+
GUIContent content = EditorGUIUtility.ObjectContent(go, typeof(GameObject));
6878
Vector2 currentSize = buttonStyle.CalcSize(content);
6979
if (currentSize.x > size.x)
7080
{
7181
size.x = currentSize.x;
7282
}
73-
74-
size.y += currentSize.y + sizeYspacing;
7583
}
7684

77-
size.x += sizeXPadding;
78-
size.y += sizeYPadding;
85+
//This is needed because CalcSize calculates content drawing with icon at full size.
86+
size.x += sizeXOffset;
87+
88+
buttonSize.x = size.x;
89+
buttonSize.y = buttonYSize;
90+
91+
size.y = gameObjects.Count * buttonYSize + sizeYPadding * 2.0f + buttonYSpacing * gameObjects.Count - 1;
92+
size.x += sizeXPadding * 2.0f;
7993

8094
return size;
8195
}
@@ -109,6 +123,11 @@ private void OnGUI()
109123
InitializeStyle();
110124
}
111125

126+
if (Event.current.type == EventType.Layout)
127+
{
128+
return;
129+
}
130+
112131
//Debug.Log($"Event : {Event.current.type}");
113132

114133
if (Event.current.type == EventType.MouseMove)
@@ -127,37 +146,194 @@ private void OnGUI()
127146

128147
private void OnGUI_Normal()
129148
{
149+
Rect rect = new Rect(sizeXPadding, sizeYPadding, buttonSize.x, buttonSize.y);
150+
130151
for (int i = 0; i < gameObjects.Count; i++)
131152
{
132153
GameObject gameObject = gameObjects[i];
133-
if (GUILayout.Button(gameObjectPaths[i], buttonStyle))
154+
155+
if(gameObject == null)
134156
{
135-
Selection.activeGameObject = gameObject;
136-
Event.current.Use();
137-
Close();
157+
//Can happen when something removes the gameobject during the window display.
158+
continue;
138159
}
160+
161+
GUIContent content = EditorGUIUtility.ObjectContent(gameObject, typeof(GameObject));
162+
163+
bool objectSelected = Selection.Contains(gameObject);
164+
165+
if (objectSelected)
166+
{
167+
GUI.backgroundColor = selectionColor;
168+
}
169+
170+
if (GUI.Button(rect, content, buttonStyle))
171+
{
172+
GameObjectButtonPress(i);
173+
}
174+
175+
GUI.backgroundColor = Color.white;
176+
177+
rect.y += buttonYSize + buttonYSpacing;
139178
}
140179
}
141180

142181
private void OnGUI_MouseMove()
143182
{
183+
Rect rect = new Rect(sizeXPadding, sizeYPadding, buttonSize.x, buttonSize.y);
184+
144185
for (int i = 0; i < gameObjects.Count; i++)
145186
{
146187
GameObject gameObject = gameObjects[i];
147-
if (GUILayout.Button(gameObjectPaths[i], buttonStyle))
188+
189+
if (gameObject == null)
148190
{
149-
Selection.activeGameObject = gameObject;
150-
Event.current.Use();
151-
Close();
191+
//Can happen when something removes the gameobject during the window display.
192+
continue;
152193
}
153194

154-
Rect lastRect = GUILayoutUtility.GetLastRect();
195+
GUIContent content = EditorGUIUtility.ObjectContent(gameObject, typeof(GameObject));
155196

156-
if (lastRect.Contains(Event.current.mousePosition))
197+
GUI.Button(rect, content, buttonStyle);
198+
199+
if (rect.Contains(Event.current.mousePosition))
157200
{
158201
HighlightedObject = gameObject;
159202
}
203+
204+
rect.y += buttonYSize + buttonYSpacing;
205+
}
206+
}
207+
208+
private void GameObjectButtonPress(int id)
209+
{
210+
SelectObject(id, Event.current.control, Event.current.shift);
211+
212+
if (Event.current.control || Event.current.shift)
213+
{
214+
return;
215+
}
216+
217+
Close();
218+
}
219+
220+
private void UpdateShiftSelectionIDs(int id)
221+
{
222+
if(shiftLastID == -1)
223+
{
224+
shiftLastID = id;
225+
}
226+
227+
if(shiftMinSelectionID == -1)
228+
{
229+
shiftMinSelectionID = id;
230+
}
231+
232+
if (shiftMaxSelectionID == -1)
233+
{
234+
shiftMaxSelectionID = id;
235+
}
236+
237+
if(id < shiftMinSelectionID)
238+
{
239+
shiftMinSelectionID = id;
160240
}
241+
else if(id >= shiftMaxSelectionID)
242+
{
243+
shiftMaxSelectionID = id;
244+
}
245+
else if(id > shiftMinSelectionID)
246+
{
247+
//ID is between min and max.
248+
if(shiftLastID < id)
249+
{
250+
shiftMaxSelectionID = id;
251+
}
252+
else
253+
{
254+
shiftMinSelectionID = id;
255+
}
256+
}
257+
258+
shiftLastID = id;
259+
}
260+
261+
private void SelectObject(int id, bool control, bool shift)
262+
{
263+
GameObject gameObject = gameObjects[id];
264+
265+
if (shift)
266+
{
267+
UpdateShiftSelectionIDs(id);
268+
SelectObjects(shiftMinSelectionID, shiftMaxSelectionID);
269+
}
270+
else if (control)
271+
{
272+
UpdateShiftSelectionIDs(id);
273+
274+
if (Selection.Contains(gameObject))
275+
{
276+
//Deselect
277+
RemoveObjectFromSelection(gameObject);
278+
}
279+
else
280+
{
281+
//Select
282+
AddObjectToSelection(gameObject);
283+
}
284+
}
285+
else
286+
{
287+
Selection.objects = new Object[] { gameObject };
288+
}
289+
}
290+
291+
private void SelectObjects(int minID, int maxID)
292+
{
293+
int size = maxID - minID + 1;
294+
Object[] newSelection = new Object[size];
295+
296+
int index = 0;
297+
298+
for (int i = minID; i <= maxID; i++)
299+
{
300+
newSelection[index] = gameObjects[i];
301+
index++;
302+
}
303+
304+
Selection.objects = newSelection;
305+
}
306+
307+
private void AddObjectToSelection(GameObject gameObject)
308+
{
309+
Object[] currentSelection = Selection.objects;
310+
Object[] newSelection = new Object[currentSelection.Length + 1];
311+
312+
currentSelection.CopyTo(newSelection, 0);
313+
newSelection[newSelection.Length - 1] = gameObject;
314+
315+
Selection.objects = newSelection;
316+
}
317+
318+
private void RemoveObjectFromSelection(GameObject gameObject)
319+
{
320+
Object[] currentSelection = Selection.objects;
321+
Object[] newSelection = new Object[currentSelection.Length - 1];
322+
323+
int index = 0;
324+
325+
for (int i = 0; i < currentSelection.Length; i++)
326+
{
327+
if (currentSelection[i] == gameObject)
328+
{
329+
continue;
330+
}
331+
332+
newSelection[index] = currentSelection[i];
333+
index++;
334+
}
335+
336+
Selection.objects = newSelection;
161337
}
162338

163339
private void OnGUI_MouseLeave()

Assets/Editor Toolbox/Editor/ToolboxEditorSettings.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ internal class ToolboxEditorSettings : ScriptableObject, IToolboxGeneralSettings
9090
private List<FolderData> customFolders = new List<FolderData>();
9191

9292
[SerializeField]
93-
private bool useToolboxScene = true;
93+
private bool useToolboxSceneView = true;
9494

9595
[SerializeField]
9696
private KeyCode selectorKey = KeyCode.LeftControl;
@@ -116,7 +116,7 @@ internal class ToolboxEditorSettings : ScriptableObject, IToolboxGeneralSettings
116116
private bool hierarchySettingsDirty;
117117
private bool projectSettingsDirty;
118118
private bool inspectorSettingsDirty;
119-
private bool sceneSettingsDirty;
119+
private bool sceneViewSettingsDirty;
120120

121121
internal event Action<IToolboxHierarchySettings> OnHierarchySettingsChanged;
122122
internal event Action<IToolboxProjectSettings> OnProjectSettingsChanged;
@@ -136,7 +136,7 @@ internal void SetHierarchySettingsDirty()
136136
/// <summary>
137137
/// Forces Project settings validation in the next <see cref="OnValidate"/> call.
138138
/// </summary>
139-
internal void SetSceneViewSettingsDirty()
139+
internal void SetProjectSettingsDirty()
140140
{
141141
projectSettingsDirty = true;
142142
}
@@ -152,9 +152,9 @@ internal void SetInspectorSettingsDirty()
152152
/// <summary>
153153
/// Forces Scene settings validation in the next <see cref="OnValidate"/> call.
154154
/// </summary>
155-
internal void SetSceneSettingsDirty()
155+
internal void SetSceneViewSettingsDirty()
156156
{
157-
sceneSettingsDirty = true;
157+
sceneViewSettingsDirty = true;
158158
}
159159

160160
internal void ValidateHierarchySettings()
@@ -172,7 +172,7 @@ internal void ValidateInspectorSettings()
172172
OnInspectorSettingsChanged?.Invoke(this);
173173
}
174174

175-
internal void ValidateSceneSettings()
175+
internal void ValidateSceneViewSettings()
176176
{
177177
OnSceneViewSettingsChanged?.Invoke(this);
178178
}
@@ -182,7 +182,7 @@ internal void Validate()
182182
ValidateHierarchySettings();
183183
ValidateProjectSettings();
184184
ValidateInspectorSettings();
185-
ValidateSceneSettings();
185+
ValidateSceneViewSettings();
186186
}
187187

188188

@@ -211,9 +211,9 @@ private void OnValidate()
211211
ValidateInspectorSettings();
212212
}
213213

214-
if (sceneSettingsDirty)
214+
if (sceneViewSettingsDirty)
215215
{
216-
ValidateSceneSettings();
216+
ValidateSceneViewSettings();
217217
}
218218
}
219219
else
@@ -396,8 +396,8 @@ public List<FolderData> CustomFolders
396396

397397
public bool UseToolboxSceneView
398398
{
399-
get => useToolboxScene;
400-
set => useToolboxScene = value;
399+
get => useToolboxSceneView;
400+
set => useToolboxSceneView = value;
401401
}
402402

403403
public KeyCode SelectorKey

0 commit comments

Comments
 (0)