com.wallstop-studios.unity-helpers 2.0.0-rc74.1 → 2.0.0-rc74.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,52 @@
1
+ namespace WallstopStudios.UnityHelpers.Editor.Utils
2
+ {
3
+ #if UNITY_EDITOR
4
+ using System;
5
+ using UnityEditor;
6
+ using UnityEngine;
7
+ using Object = UnityEngine.Object;
8
+
9
+ [InitializeOnLoad]
10
+ public static class ScriptableObjectSingletonCreator
11
+ {
12
+ static ScriptableObjectSingletonCreator()
13
+ {
14
+ bool anyCreated = false;
15
+ foreach (
16
+ Type derivedType in TypeCache.GetTypesDerivedFrom(
17
+ typeof(UnityHelpers.Utils.ScriptableObjectSingleton<>)
18
+ )
19
+ )
20
+ {
21
+ if (!derivedType.IsAbstract && !derivedType.IsGenericType)
22
+ {
23
+ Object[] existing = Resources.LoadAll(string.Empty, derivedType);
24
+ if (existing.Length != 0)
25
+ {
26
+ continue;
27
+ }
28
+
29
+ if (!AssetDatabase.IsValidFolder("Assets/Resources"))
30
+ {
31
+ AssetDatabase.CreateFolder("Assets", "Resources");
32
+ }
33
+
34
+ ScriptableObject instance = ScriptableObject.CreateInstance(derivedType);
35
+ string assetPathName = AssetDatabase.GenerateUniqueAssetPath(
36
+ "Assets/Resources/" + derivedType.Name + ".asset"
37
+ );
38
+ AssetDatabase.CreateAsset(instance, assetPathName);
39
+ Debug.Log($"Creating missing singleton for type {derivedType.Name}.");
40
+ anyCreated = true;
41
+ }
42
+ }
43
+
44
+ if (anyCreated)
45
+ {
46
+ AssetDatabase.SaveAssets();
47
+ AssetDatabase.Refresh();
48
+ }
49
+ }
50
+ }
51
+ #endif
52
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 7dc31b57f14246e78ea4686c7acc64b7
3
+ timeCreated: 1747541418
@@ -7,7 +7,6 @@
7
7
  using System.Reflection;
8
8
  using Extension;
9
9
  using Helper;
10
- using Helper.Partials;
11
10
  using JetBrains.Annotations;
12
11
  using UnityEngine;
13
12
 
@@ -7,7 +7,6 @@
7
7
  using System.Reflection;
8
8
  using DataStructure.Adapters;
9
9
  using Extension;
10
- using Partials;
11
10
  using Random;
12
11
  using UnityEngine;
13
12
  using Utils;
@@ -132,7 +131,8 @@
132
131
  public static GameObject FindChildGameObjectWithTag(this GameObject gameObject, string tag)
133
132
  {
134
133
  return gameObject
135
- .IterateOverChildGameObjectsRecursivelyIncludingSelf()
134
+ .transform.IterateOverAllChildrenRecursively(includeSelf: true)
135
+ .Select(t => t.gameObject)
136
136
  .FirstOrDefault(child => child.CompareTag(tag));
137
137
  }
138
138
 
@@ -485,7 +485,8 @@
485
485
  )
486
486
  {
487
487
  return gameObject
488
- .IterateOverChildGameObjectsRecursivelyIncludingSelf()
488
+ .transform.IterateOverAllChildrenRecursively(includeSelf: true)
489
+ .Select(t => t.gameObject)
489
490
  .FirstOrDefault(go => go.CompareTag(tag));
490
491
  }
491
492
 
@@ -1,6 +1,5 @@
1
1
  namespace WallstopStudios.UnityHelpers.Core.Helper
2
2
  {
3
- using Partials;
4
3
  using Object = UnityEngine.Object;
5
4
 
6
5
  public static class LifetimeHelpers
@@ -1,79 +1,107 @@
1
- namespace WallstopStudios.UnityHelpers.Core.Helper.Partials
1
+ namespace WallstopStudios.UnityHelpers.Core.Helper
2
2
  {
3
3
  using System.Collections.Generic;
4
4
  using UnityEngine;
5
+ using Utils;
5
6
 
6
7
  public static partial class Helpers
7
8
  {
8
- public static IEnumerable<GameObject> IterateOverChildGameObjects(
9
- this GameObject gameObject
9
+ public static List<T> IterateOverAllParentComponentsRecursively<T>(
10
+ this Component component,
11
+ List<T> buffer,
12
+ bool includeSelf = false
10
13
  )
11
14
  {
12
- for (int i = 0; i < gameObject.transform.childCount; i++)
15
+ buffer.Clear();
16
+ if (component == null)
13
17
  {
14
- yield return gameObject.transform.GetChild(i).gameObject;
18
+ return buffer;
15
19
  }
16
- }
17
20
 
18
- public static IEnumerable<GameObject> IterateOverChildGameObjectsRecursively(
19
- this GameObject gameObject
20
- )
21
- {
22
- for (int i = 0; i < gameObject.transform.childCount; i++)
21
+ List<T> internalBuffer = Buffers<T>.List;
22
+ if (includeSelf)
23
23
  {
24
- GameObject child = gameObject.transform.GetChild(i).gameObject;
25
- yield return child;
26
- foreach (GameObject go in child.IterateOverChildGameObjectsRecursively())
24
+ component.GetComponents(internalBuffer);
25
+ foreach (T c in internalBuffer)
27
26
  {
28
- yield return go;
27
+ buffer.Add(c);
29
28
  }
30
29
  }
30
+
31
+ Transform parent = component.transform.parent;
32
+ while (parent != null)
33
+ {
34
+ parent.GetComponents(internalBuffer);
35
+ foreach (T c in internalBuffer)
36
+ {
37
+ buffer.Add(c);
38
+ }
39
+ parent = parent.parent;
40
+ }
41
+
42
+ return buffer;
31
43
  }
32
44
 
33
- public static IEnumerable<GameObject> IterateOverChildGameObjectsRecursivelyIncludingSelf(
34
- this GameObject gameObject
45
+ public static IEnumerable<T> IterateOverAllParentComponentsRecursively<T>(
46
+ this Component component,
47
+ bool includeSelf = false
35
48
  )
36
49
  {
37
- yield return gameObject;
50
+ if (component == null)
51
+ {
52
+ yield break;
53
+ }
38
54
 
39
- for (int i = 0; i < gameObject.transform.childCount; ++i)
55
+ List<T> buffer = new();
56
+ foreach (Transform parent in IterateOverAllParents(component, includeSelf))
40
57
  {
41
- GameObject child = gameObject.transform.GetChild(i).gameObject;
42
- foreach (
43
- GameObject c in child.IterateOverChildGameObjectsRecursivelyIncludingSelf()
44
- )
58
+ parent.GetComponents(buffer);
59
+ foreach (T c in buffer)
45
60
  {
46
61
  yield return c;
47
62
  }
48
63
  }
49
64
  }
50
65
 
51
- public static IEnumerable<GameObject> IterateOverParentGameObjects(
52
- this GameObject gameObject
66
+ public static List<T> IterateOverAllChildComponentsRecursively<T>(
67
+ this Component component,
68
+ List<T> buffer,
69
+ bool includeSelf = false
53
70
  )
54
71
  {
55
- Transform currentTransform = gameObject.transform.parent;
56
- while (currentTransform != null)
72
+ buffer.Clear();
73
+ if (component == null)
57
74
  {
58
- yield return currentTransform.gameObject;
59
- currentTransform = currentTransform.parent;
75
+ return buffer;
60
76
  }
61
- }
62
77
 
63
- public static IEnumerable<GameObject> IterateOverParentGameObjectsRecursivelyIncludingSelf(
64
- this GameObject gameObject
65
- )
66
- {
67
- yield return gameObject;
78
+ List<T> internalBuffer = Buffers<T>.List;
79
+ if (includeSelf)
80
+ {
81
+ component.GetComponents(internalBuffer);
82
+ foreach (T c in internalBuffer)
83
+ {
84
+ buffer.Add(c);
85
+ }
86
+ }
68
87
 
69
- foreach (GameObject parent in IterateOverParentGameObjects(gameObject))
88
+ Transform transform = component.transform;
89
+ for (int i = 0; i < transform.childCount; ++i)
70
90
  {
71
- yield return parent;
91
+ Transform child = transform.GetChild(i);
92
+ child.GetComponentsInChildren(true, internalBuffer);
93
+ foreach (T c in internalBuffer)
94
+ {
95
+ buffer.Add(c);
96
+ }
72
97
  }
98
+
99
+ return buffer;
73
100
  }
74
101
 
75
102
  public static IEnumerable<T> IterateOverAllChildComponentsRecursively<T>(
76
- this Component component
103
+ this Component component,
104
+ bool includeSelf = false
77
105
  )
78
106
  {
79
107
  if (component == null)
@@ -81,52 +109,79 @@
81
109
  yield break;
82
110
  }
83
111
 
84
- foreach (T c in component.gameObject.GetComponents<T>())
112
+ List<T> buffer = new();
113
+ if (includeSelf)
85
114
  {
86
- yield return c;
115
+ component.GetComponents(buffer);
116
+ foreach (T c in buffer)
117
+ {
118
+ yield return c;
119
+ }
87
120
  }
88
121
 
89
- for (int i = 0; i < component.transform.childCount; ++i)
122
+ Transform transform = component.transform;
123
+ for (int i = 0; i < transform.childCount; ++i)
90
124
  {
91
- Transform child = component.transform.GetChild(i);
92
-
93
- foreach (T c in child.IterateOverAllChildComponentsRecursively<T>())
125
+ Transform child = transform.GetChild(i);
126
+ child.GetComponentsInChildren(true, buffer);
127
+ foreach (T c in buffer)
94
128
  {
95
129
  yield return c;
96
130
  }
97
131
  }
98
132
  }
99
133
 
100
- public static IEnumerable<Transform> IterateOverAllChildren(this Component component)
134
+ public static IEnumerable<Transform> IterateOverAllChildren(
135
+ this Component component,
136
+ bool includeSelf = false
137
+ )
101
138
  {
102
139
  if (component == null)
103
140
  {
104
141
  yield break;
105
142
  }
106
143
 
107
- for (int i = 0; i < component.transform.childCount; ++i)
144
+ Transform transform = component.transform;
145
+ if (includeSelf)
146
+ {
147
+ yield return transform;
148
+ }
149
+
150
+ for (int i = 0; i < transform.childCount; ++i)
108
151
  {
109
- yield return component.transform.GetChild(i);
152
+ yield return transform.GetChild(i);
110
153
  }
111
154
  }
112
155
 
113
- public static IEnumerable<Transform> IterateOverAllParents(this Component component)
156
+ public static List<Transform> IterateOverAllChildren(
157
+ this Component component,
158
+ List<Transform> buffer,
159
+ bool includeSelf = false
160
+ )
114
161
  {
162
+ buffer.Clear();
115
163
  if (component == null)
116
164
  {
117
- yield break;
165
+ return buffer;
118
166
  }
119
167
 
120
168
  Transform transform = component.transform;
121
- while (transform.parent != null)
169
+ if (includeSelf)
170
+ {
171
+ buffer.Add(transform);
172
+ }
173
+
174
+ for (int i = 0; i < transform.childCount; ++i)
122
175
  {
123
- yield return transform.parent;
124
- transform = transform.parent;
176
+ buffer.Add(transform.GetChild(i));
125
177
  }
178
+
179
+ return buffer;
126
180
  }
127
181
 
128
- public static IEnumerable<Transform> IterateOverAllParentsIncludingSelf(
129
- this Component component
182
+ public static IEnumerable<Transform> IterateOverAllParents(
183
+ this Component component,
184
+ bool includeSelf = false
130
185
  )
131
186
  {
132
187
  if (component == null)
@@ -135,15 +190,50 @@
135
190
  }
136
191
 
137
192
  Transform transform = component.transform;
138
- while (transform != null)
193
+ if (includeSelf)
139
194
  {
140
195
  yield return transform;
141
- transform = transform.parent;
142
196
  }
197
+
198
+ Transform parent = transform.parent;
199
+ while (parent != null)
200
+ {
201
+ yield return parent;
202
+ parent = parent.parent;
203
+ }
204
+ }
205
+
206
+ public static List<Transform> IterateOverAllParents(
207
+ this Component component,
208
+ List<Transform> buffer,
209
+ bool includeSelf = false
210
+ )
211
+ {
212
+ buffer.Clear();
213
+ if (component == null)
214
+ {
215
+ return buffer;
216
+ }
217
+
218
+ Transform transform = component.transform;
219
+ if (includeSelf)
220
+ {
221
+ buffer.Add(transform);
222
+ }
223
+
224
+ Transform parent = transform.parent;
225
+ while (parent != null)
226
+ {
227
+ buffer.Add(parent);
228
+ parent = parent.parent;
229
+ }
230
+
231
+ return buffer;
143
232
  }
144
233
 
145
234
  public static IEnumerable<Transform> IterateOverAllChildrenRecursively(
146
- this Component component
235
+ this Component component,
236
+ bool includeSelf = false
147
237
  )
148
238
  {
149
239
  if (component == null)
@@ -151,21 +241,65 @@
151
241
  yield break;
152
242
  }
153
243
 
154
- for (int i = 0; i < component.transform.childCount; ++i)
244
+ Transform transform = component.transform;
245
+ if (includeSelf)
246
+ {
247
+ yield return transform;
248
+ }
249
+
250
+ for (int i = 0; i < transform.childCount; ++i)
155
251
  {
156
- Transform childTransform = component.transform.GetChild(i);
157
- yield return childTransform;
158
252
  foreach (
159
- Transform childChildTransform in childTransform.IterateOverAllChildrenRecursively()
253
+ Transform child in IterateOverAllChildrenRecursively(
254
+ transform.GetChild(i),
255
+ includeSelf: true
256
+ )
160
257
  )
161
258
  {
162
- yield return childChildTransform;
259
+ yield return child;
163
260
  }
164
261
  }
165
262
  }
166
263
 
264
+ public static List<Transform> IterateOverAllChildrenRecursively(
265
+ this Component component,
266
+ List<Transform> buffer,
267
+ bool includeSelf = false
268
+ )
269
+ {
270
+ buffer.Clear();
271
+ if (component == null)
272
+ {
273
+ return buffer;
274
+ }
275
+
276
+ Transform transform = component.transform;
277
+ if (includeSelf)
278
+ {
279
+ buffer.Add(transform);
280
+ }
281
+
282
+ return InternalIterateOverAllChildrenRecursively(transform, buffer);
283
+ }
284
+
285
+ private static List<Transform> InternalIterateOverAllChildrenRecursively(
286
+ this Transform transform,
287
+ List<Transform> buffer
288
+ )
289
+ {
290
+ for (int i = 0; i < transform.childCount; ++i)
291
+ {
292
+ Transform child = transform.GetChild(i);
293
+ buffer.Add(child);
294
+ InternalIterateOverAllChildrenRecursively(child, buffer);
295
+ }
296
+
297
+ return buffer;
298
+ }
299
+
167
300
  public static IEnumerable<Transform> IterateOverAllChildrenRecursivelyBreadthFirst(
168
- this Component component
301
+ this Component component,
302
+ bool includeSelf = false
169
303
  )
170
304
  {
171
305
  if (component == null)
@@ -173,8 +307,14 @@
173
307
  yield break;
174
308
  }
175
309
 
310
+ Transform transform = component.transform;
311
+ if (includeSelf)
312
+ {
313
+ yield return transform;
314
+ }
315
+
176
316
  Queue<Transform> iteration = new();
177
- iteration.Enqueue(component.transform);
317
+ iteration.Enqueue(transform);
178
318
  while (iteration.TryDequeue(out Transform current))
179
319
  {
180
320
  for (int i = 0; i < current.childCount; ++i)
@@ -185,5 +325,38 @@
185
325
  }
186
326
  }
187
327
  }
328
+
329
+ public static List<Transform> IterateOverAllChildrenRecursivelyBreadthFirst(
330
+ this Component component,
331
+ List<Transform> buffer,
332
+ bool includeSelf = false
333
+ )
334
+ {
335
+ buffer.Clear();
336
+ if (component == null)
337
+ {
338
+ return buffer;
339
+ }
340
+
341
+ Transform transform = component.transform;
342
+ if (includeSelf)
343
+ {
344
+ buffer.Add(transform);
345
+ }
346
+
347
+ Queue<Transform> iteration = Buffers<Transform>.Queue;
348
+ iteration.Clear();
349
+ iteration.Enqueue(transform);
350
+ while (iteration.TryDequeue(out Transform current))
351
+ {
352
+ for (int i = 0; i < current.childCount; ++i)
353
+ {
354
+ Transform childTransform = current.GetChild(i);
355
+ iteration.Enqueue(childTransform);
356
+ buffer.Add(childTransform);
357
+ }
358
+ }
359
+ return buffer;
360
+ }
188
361
  }
189
362
  }
@@ -5,14 +5,23 @@
5
5
  using Core.Extension;
6
6
  using Core.Helper;
7
7
  using UnityEngine;
8
+ #if ODIN_INSPECTOR
9
+ using Sirenix.OdinInspector;
10
+ #endif
8
11
 
9
12
  [DisallowMultipleComponent]
10
- public abstract class RuntimeSingleton<T> : MonoBehaviour
13
+ public abstract class RuntimeSingleton<T> :
14
+ #if ODIN_INSPECTOR
15
+ SerializedMonoBehaviour
16
+ #else
17
+ MonoBehaviour
18
+ #endif
11
19
  where T : RuntimeSingleton<T>
12
20
  {
13
21
  public static bool HasInstance => _instance != null;
14
22
 
15
23
  protected static T _instance;
24
+ protected static bool _isQuitting;
16
25
 
17
26
  protected virtual bool Preserve => true;
18
27
 
@@ -25,6 +34,11 @@
25
34
  return _instance;
26
35
  }
27
36
 
37
+ if (_isQuitting)
38
+ {
39
+ return null;
40
+ }
41
+
28
42
  Type type = typeof(T);
29
43
  GameObject instance = new($"{type.Name}-Singleton", type);
30
44
  if (
@@ -67,5 +81,10 @@
67
81
  _instance = null;
68
82
  }
69
83
  }
84
+
85
+ protected virtual void OnApplicationQuit()
86
+ {
87
+ _isQuitting = true;
88
+ }
70
89
  }
71
90
  }
@@ -0,0 +1,44 @@
1
+ namespace WallstopStudios.UnityHelpers.Utils
2
+ {
3
+ using System;
4
+ using UnityEngine;
5
+ #if ODIN_INSPECTOR
6
+ using Sirenix.OdinInspector;
7
+ #endif
8
+
9
+ public abstract class ScriptableObjectSingleton<T> :
10
+ #if ODIN_INSPECTOR
11
+ SerializedScriptableObject
12
+ #else
13
+ ScriptableObject
14
+ #endif
15
+ where T : ScriptableObjectSingleton<T>
16
+ {
17
+ protected static readonly Lazy<T> LazyInstance = new(() =>
18
+ {
19
+ T[] instances = Resources.LoadAll<T>(string.Empty);
20
+ switch (instances.Length)
21
+ {
22
+ case 1:
23
+ {
24
+ return instances[0];
25
+ }
26
+ case 0:
27
+ {
28
+ Debug.LogError($"Failed to find ScriptableSingleton of type {typeof(T).Name}.");
29
+ return null;
30
+ }
31
+ }
32
+
33
+ Debug.LogWarning(
34
+ $"Found multiple ScriptableSingletons of type {typeof(T).Name}, defaulting to first by name."
35
+ );
36
+ Array.Sort(instances, UnityObjectNameComparer<T>.Instance);
37
+ return instances[0];
38
+ });
39
+
40
+ public static bool HasInstance => LazyInstance.IsValueCreated && LazyInstance.Value != null;
41
+
42
+ public static T Instance => LazyInstance.Value;
43
+ }
44
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: b45bfc0f847a4d13ad5458b06a424c7c
3
+ timeCreated: 1747539772
@@ -2,6 +2,9 @@
2
2
  {
3
3
  using System;
4
4
  using System.Collections.Generic;
5
+ #if UNITY_EDITOR
6
+ using UnityEditor;
7
+ #endif
5
8
 
6
9
  public sealed class UnityObjectNameComparer<T> : IComparer<T>
7
10
  where T : UnityEngine.Object
@@ -27,7 +30,25 @@
27
30
  return -1;
28
31
  }
29
32
 
30
- return string.Compare(x.name, y.name, StringComparison.OrdinalIgnoreCase);
33
+ int comparison = string.Compare(x.name, y.name, StringComparison.OrdinalIgnoreCase);
34
+ if (comparison != 0)
35
+ {
36
+ return comparison;
37
+ }
38
+
39
+ #if UNITY_EDITOR
40
+ comparison = string.Compare(
41
+ AssetDatabase.GetAssetOrScenePath(x),
42
+ AssetDatabase.GetAssetOrScenePath(y),
43
+ StringComparison.OrdinalIgnoreCase
44
+ );
45
+ #endif
46
+ if (comparison == 0)
47
+ {
48
+ return x.GetInstanceID().CompareTo(y.GetInstanceID());
49
+ }
50
+
51
+ return comparison;
31
52
  }
32
53
  }
33
54
  }
@@ -2,7 +2,6 @@
2
2
  {
3
3
  using System.Collections;
4
4
  using Core.Helper;
5
- using Core.Helper.Partials;
6
5
  using JetBrains.Annotations;
7
6
  using NUnit.Framework;
8
7
  using UnityEngine;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "com.wallstop-studios.unity-helpers",
3
- "version": "2.0.0-rc74.1",
3
+ "version": "2.0.0-rc74.3",
4
4
  "displayName": "Unity Helpers",
5
5
  "description": "Various Unity Helper Library",
6
6
  "dependencies": {},
@@ -54,6 +54,8 @@
54
54
 
55
55
 
56
56
 
57
+
58
+
57
59
 
58
60
 
59
61