com.wallstop-studios.unity-helpers 1.0.0-rc8 → 1.0.1-rc01

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.
@@ -55,7 +55,9 @@
55
55
 
56
56
  if (log)
57
57
  {
58
- component.LogWarn("Failed to find {0} on {1} (name: {2}), id [{3}].", typeof(T).Name, tag, gameObject.name, gameObject.GetInstanceID());
58
+ component.LogWarn(
59
+ "Failed to find {0} on {1} (name: {2}), id [{3}].", typeof(T).Name, tag, gameObject.name,
60
+ gameObject.GetInstanceID());
59
61
  }
60
62
 
61
63
  return default;
@@ -111,9 +113,9 @@
111
113
  }
112
114
  }
113
115
 
114
- public static bool HasComponent<T>(this Object unityObject)
116
+ public static bool HasComponent<T>(this Object unityObject) where T : Object
115
117
  {
116
- return (unityObject) switch
118
+ return unityObject switch
117
119
  {
118
120
  GameObject go => go.HasComponent<T>(),
119
121
  Component component => component.HasComponent<T>(),
@@ -121,12 +123,12 @@
121
123
  };
122
124
  }
123
125
 
124
- public static bool HasComponent<T>(this Component component)
126
+ public static bool HasComponent<T>(this Component component) where T : Object
125
127
  {
126
128
  return component.TryGetComponent<T>(out _);
127
129
  }
128
130
 
129
- public static bool HasComponent<T>(this GameObject gameObject)
131
+ public static bool HasComponent<T>(this GameObject gameObject) where T : Object
130
132
  {
131
133
  return gameObject.TryGetComponent<T>(out _);
132
134
  }
@@ -162,7 +164,8 @@
162
164
  }
163
165
  }
164
166
 
165
- public static IEnumerable<GameObject> IterateOverChildGameObjectsRecursivelyIncludingSelf(this GameObject gameObject)
167
+ public static IEnumerable<GameObject> IterateOverChildGameObjectsRecursivelyIncludingSelf(
168
+ this GameObject gameObject)
166
169
  {
167
170
  yield return gameObject;
168
171
 
@@ -186,7 +189,8 @@
186
189
  }
187
190
  }
188
191
 
189
- public static IEnumerable<GameObject> IterateOverParentGameObjectsRecursivelyIncludingSelf(this GameObject gameObject)
192
+ public static IEnumerable<GameObject> IterateOverParentGameObjectsRecursivelyIncludingSelf(
193
+ this GameObject gameObject)
190
194
  {
191
195
  yield return gameObject;
192
196
 
@@ -225,7 +229,8 @@
225
229
  }
226
230
  }
227
231
 
228
- public static void EnableRendererRecursively<T>(this Component component, bool enabled,
232
+ public static void EnableRendererRecursively<T>(
233
+ this Component component, bool enabled,
229
234
  Func<T, bool> exclude = null) where T : Renderer
230
235
  {
231
236
  if (component == null)
@@ -388,31 +393,36 @@
388
393
  }
389
394
  }
390
395
 
391
- public static void DestroyAllChildrenGameObjectsImmediatelyConditionally(this GameObject gameObject,
396
+ public static void DestroyAllChildrenGameObjectsImmediatelyConditionally(
397
+ this GameObject gameObject,
392
398
  Func<GameObject, bool> acceptancePredicate)
393
399
  {
394
- InternalDestroyAllChildrenGameObjects(gameObject, toDestroy =>
395
- {
396
- if (!acceptancePredicate(toDestroy))
400
+ InternalDestroyAllChildrenGameObjects(
401
+ gameObject, toDestroy =>
397
402
  {
398
- return;
399
- }
403
+ if (!acceptancePredicate(toDestroy))
404
+ {
405
+ return;
406
+ }
400
407
 
401
- Object.DestroyImmediate(toDestroy);
402
- });
408
+ Object.DestroyImmediate(toDestroy);
409
+ });
403
410
  }
404
411
 
405
- public static void DestroyAllChildGameObjectsConditionally(this GameObject gameObject,
412
+ public static void DestroyAllChildGameObjectsConditionally(
413
+ this GameObject gameObject,
406
414
  Func<GameObject, bool> acceptancePredicate)
407
415
  {
408
- InternalDestroyAllChildrenGameObjects(gameObject, toDestroy =>
409
- {
410
- if (!acceptancePredicate(toDestroy))
416
+ InternalDestroyAllChildrenGameObjects(
417
+ gameObject, toDestroy =>
411
418
  {
412
- return;
413
- }
414
- toDestroy.Destroy();
415
- });
419
+ if (!acceptancePredicate(toDestroy))
420
+ {
421
+ return;
422
+ }
423
+
424
+ toDestroy.Destroy();
425
+ });
416
426
  }
417
427
 
418
428
  public static void DestroyAllChildrenGameObjectsImmediately(this GameObject gameObject) =>
@@ -424,7 +434,8 @@
424
434
  public static void EditorDestroyAllChildrenGameObjects(this GameObject gameObject) =>
425
435
  InternalDestroyAllChildrenGameObjects(gameObject, go => go.Destroy());
426
436
 
427
- private static void InternalDestroyAllChildrenGameObjects(this GameObject gameObject,
437
+ private static void InternalDestroyAllChildrenGameObjects(
438
+ this GameObject gameObject,
428
439
  Action<GameObject> destroyFunction)
429
440
  {
430
441
  for (int i = gameObject.transform.childCount - 1; 0 <= i; --i)
@@ -441,8 +452,16 @@
441
452
  {
442
453
  return true;
443
454
  }
444
- #endif
455
+
456
+ return PrefabUtility.GetPrefabAssetType(gameObject) switch
457
+ {
458
+ PrefabAssetType.NotAPrefab => false,
459
+ PrefabAssetType.MissingAsset => scene.rootCount == 0,
460
+ _ => true,
461
+ };
462
+ #else
445
463
  return scene.rootCount == 0;
464
+ #endif
446
465
  }
447
466
 
448
467
  public static bool IsPrefab(this Component component)
@@ -516,7 +535,9 @@
516
535
  }
517
536
 
518
537
  // https://gamedevelopment.tutsplus.com/tutorials/unity-solution-for-hitting-moving-targets--cms-29633
519
- public static Vector2 PredictCurrentTarget(this GameObject currentTarget, Vector2 launchLocation, float projectileSpeed, bool predictiveFiring, Vector2 targetVelocity)
538
+ public static Vector2 PredictCurrentTarget(
539
+ this GameObject currentTarget, Vector2 launchLocation, float projectileSpeed, bool predictiveFiring,
540
+ Vector2 targetVelocity)
520
541
  {
521
542
  Vector2 target = currentTarget.transform.position;
522
543
 
@@ -530,8 +551,9 @@
530
551
  return target;
531
552
  }
532
553
 
533
- float a = (targetVelocity.x * targetVelocity.x) + (targetVelocity.y * targetVelocity.y) - (projectileSpeed * projectileSpeed);
534
-
554
+ float a = (targetVelocity.x * targetVelocity.x) + (targetVelocity.y * targetVelocity.y) -
555
+ (projectileSpeed * projectileSpeed);
556
+
535
557
  float b = 2 * (targetVelocity.x * (target.x - launchLocation.x) +
536
558
  targetVelocity.y * (target.y - launchLocation.y));
537
559
 
@@ -593,7 +615,7 @@
593
615
  {
594
616
  GameObject go => go,
595
617
  Component c => c.gameObject,
596
- _ => default
618
+ _ => null
597
619
  };
598
620
  }
599
621
 
@@ -610,10 +632,12 @@
610
632
 
611
633
  public static GameObject FindChildGameObjectWithTag(this GameObject gameObject, string tag)
612
634
  {
613
- return gameObject.IterateOverChildGameObjectsRecursivelyIncludingSelf().FirstOrDefault(child => child.CompareTag(tag));
635
+ return gameObject.IterateOverChildGameObjectsRecursivelyIncludingSelf()
636
+ .FirstOrDefault(child => child.CompareTag(tag));
614
637
  }
615
638
 
616
- public static bool HasLineOfSight(Vector2 initialLocation, Vector2 direction, Transform transform, float totalDistance, float delta)
639
+ public static bool HasLineOfSight(
640
+ Vector2 initialLocation, Vector2 direction, Transform transform, float totalDistance, float delta)
617
641
  {
618
642
  int hits = Physics2D.RaycastNonAlloc(initialLocation, direction, Buffers.RaycastHits);
619
643
  for (int i = 0; i < hits; ++i)
@@ -634,7 +658,9 @@
634
658
  return true;
635
659
  }
636
660
 
637
- public static Coroutine StartFunctionAsCoroutine(this MonoBehaviour monoBehaviour, Action action, float updateRate, bool useJitter = false, bool waitBefore = false)
661
+ public static Coroutine StartFunctionAsCoroutine(
662
+ this MonoBehaviour monoBehaviour, Action action, float updateRate, bool useJitter = false,
663
+ bool waitBefore = false)
638
664
  {
639
665
  return monoBehaviour.StartCoroutine(FunctionAsCoroutine(action, updateRate, useJitter, waitBefore));
640
666
  }
@@ -642,30 +668,51 @@
642
668
  private static IEnumerator FunctionAsCoroutine(Action action, float updateRate, bool useJitter, bool waitBefore)
643
669
  {
644
670
  bool usedJitter = false;
645
- WaitForSeconds wait = new(updateRate);
646
-
647
671
  while (true)
648
672
  {
673
+ float startTime;
649
674
  if (waitBefore)
650
675
  {
651
- // Copy-pasta the code, no way to unify in a performant way without generating garbage
652
- yield return wait;
653
676
  if (useJitter && !usedJitter)
654
677
  {
655
- yield return new WaitForSeconds(PcgRandom.Instance.NextFloat(updateRate));
678
+ float delay = PcgRandom.Instance.NextFloat(updateRate);
679
+ startTime = Time.time;
680
+ while (!HasEnoughTimePassed(startTime, delay))
681
+ {
682
+ yield return null;
683
+ }
684
+
656
685
  usedJitter = true;
657
686
  }
687
+
688
+ startTime = Time.time;
689
+ while (!HasEnoughTimePassed(startTime, updateRate))
690
+ {
691
+ yield return null;
692
+ }
658
693
  }
659
694
 
660
695
  action();
696
+
661
697
  if (!waitBefore)
662
698
  {
663
- yield return wait;
664
699
  if (useJitter && !usedJitter)
665
700
  {
666
- yield return new WaitForSeconds(PcgRandom.Instance.NextFloat(updateRate));
701
+ float delay = PcgRandom.Instance.NextFloat(updateRate);
702
+ startTime = Time.time;
703
+ while (!HasEnoughTimePassed(startTime, delay))
704
+ {
705
+ yield return null;
706
+ }
707
+
667
708
  usedJitter = true;
668
709
  }
710
+
711
+ startTime = Time.time;
712
+ while (!HasEnoughTimePassed(startTime, updateRate))
713
+ {
714
+ yield return null;
715
+ }
669
716
  }
670
717
  }
671
718
  }
@@ -727,6 +774,7 @@
727
774
  {
728
775
  yield return null;
729
776
  }
777
+
730
778
  action();
731
779
  }
732
780
 
@@ -736,7 +784,8 @@
736
784
  action();
737
785
  }
738
786
 
739
- public static bool HasEnoughTimePassed(float timestamp, float desiredDuration) => timestamp + desiredDuration < Time.time;
787
+ public static bool HasEnoughTimePassed(float timestamp, float desiredDuration) =>
788
+ timestamp + desiredDuration < Time.time;
740
789
 
741
790
  public static Vector2 Opposite(this Vector2 vector)
742
791
  {
@@ -774,12 +823,12 @@
774
823
 
775
824
  public static Vector3Int AsVector3Int(this (uint x, uint y, uint z) vector)
776
825
  {
777
- return new Vector3Int((int) vector.x, (int) vector.y, (int) vector.z);
826
+ return new Vector3Int((int)vector.x, (int)vector.y, (int)vector.z);
778
827
  }
779
828
 
780
829
  public static Vector3Int AsVector3Int(this Vector3 vector)
781
830
  {
782
- return new Vector3Int((int) Math.Round(vector.x), (int) Math.Round(vector.y), (int) Math.Round(vector.z));
831
+ return new Vector3Int((int)Math.Round(vector.x), (int)Math.Round(vector.y), (int)Math.Round(vector.z));
783
832
  }
784
833
 
785
834
  public static Vector3 AsVector3(this (uint x, uint y, uint z) vector)
@@ -829,7 +878,7 @@
829
878
  }
830
879
 
831
880
  foreach (FieldInfo field in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic)
832
- .Where(field => Attribute.IsDefined(field, typeof(SerializeField))))
881
+ .Where(field => Attribute.IsDefined(field, typeof(SerializeField))))
833
882
  {
834
883
  try
835
884
  {
@@ -881,13 +930,15 @@
881
930
 
882
931
  public static GameObject GetTagObjectInChildHierarchy(this GameObject gameObject, string tag)
883
932
  {
884
- return gameObject.IterateOverChildGameObjectsRecursivelyIncludingSelf().FirstOrDefault(go => go.CompareTag(tag));
933
+ return gameObject.IterateOverChildGameObjectsRecursivelyIncludingSelf()
934
+ .FirstOrDefault(go => go.CompareTag(tag));
885
935
  }
886
936
 
887
937
  //https://answers.unity.com/questions/722748/refreshing-the-polygon-collider-2d-upon-sprite-cha.html
888
938
  public static void UpdateShapeToSprite(this Component component)
889
939
  {
890
- if (!component.TryGetComponent(out SpriteRenderer spriteRenderer) || component.TryGetComponent(out PolygonCollider2D collider))
940
+ if (!component.TryGetComponent(out SpriteRenderer spriteRenderer) ||
941
+ component.TryGetComponent(out PolygonCollider2D collider))
891
942
  {
892
943
  return;
893
944
  }
@@ -922,7 +973,8 @@
922
973
  return new Vector3Int(x, y, z);
923
974
  }
924
975
 
925
- public static GameObject TryGetClosestParentWithComponentIncludingSelf<T>(this GameObject current) where T : Component
976
+ public static GameObject TryGetClosestParentWithComponentIncludingSelf<T>(this GameObject current)
977
+ where T : Component
926
978
  {
927
979
  while (current != null)
928
980
  {
@@ -941,7 +993,7 @@
941
993
  #if UNITY_EDITOR
942
994
  public static IEnumerable<GameObject> EnumeratePrefabs(IEnumerable<string> assetPaths = null)
943
995
  {
944
- assetPaths ??= new[] {"Assets/Prefabs", "Assets/Resources"};
996
+ assetPaths ??= new[] { "Assets/Prefabs", "Assets/Resources" };
945
997
 
946
998
  foreach (string assetGuid in AssetDatabase.FindAssets("t:prefab", assetPaths.ToArray()))
947
999
  {
@@ -954,7 +1006,8 @@
954
1006
  }
955
1007
  }
956
1008
 
957
- public static IEnumerable<T> EnumerateScriptableObjects<T>(string[] assetPaths = null) where T : ScriptableObject
1009
+ public static IEnumerable<T> EnumerateScriptableObjects<T>(string[] assetPaths = null)
1010
+ where T : ScriptableObject
958
1011
  {
959
1012
  assetPaths ??= new[] { "Assets/Prefabs", "Assets/Resources", "Assets/TileMaps" };
960
1013
 
@@ -1038,7 +1091,10 @@
1038
1091
  {
1039
1092
  foreach (MonoBehaviour script in gameObject.GetComponentsInChildren<MonoBehaviour>())
1040
1093
  {
1041
- MethodInfo awakeInfo = AwakeMethodsByType.GetOrAdd(script.GetType(), type => type.GetMethod("Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
1094
+ MethodInfo awakeInfo = AwakeMethodsByType.GetOrAdd(
1095
+ script.GetType(),
1096
+ type => type.GetMethod(
1097
+ "Awake", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
1042
1098
  if (awakeInfo != null)
1043
1099
  {
1044
1100
  _ = awakeInfo.Invoke(script, null);
@@ -1093,4 +1149,4 @@
1093
1149
  }
1094
1150
  }
1095
1151
  }
1096
- }
1152
+ }
@@ -0,0 +1,273 @@
1
+ namespace UnityHelpers.Utils
2
+ {
3
+ using System.Collections.Generic;
4
+ using System.Linq;
5
+ using UnityEngine;
6
+ using Core.Attributes;
7
+
8
+ /// <summary>
9
+ /// Keeps stack-like track of Colors and Materials of SpriteRenderers
10
+ /// </summary>
11
+ [DisallowMultipleComponent]
12
+ public sealed class SpriteRendererMetadata : MonoBehaviour
13
+ {
14
+ private readonly List<(Component component, Color color)> _colorStack = new();
15
+ private readonly List<(Component component, Material material)> _materialStack = new();
16
+
17
+ private readonly List<(Component component, Color color)> _colorStackCache = new();
18
+ private readonly List<(Component component, Material material)> _materialStackCache = new();
19
+
20
+ public Color OriginalColor => _colorStack[0].color;
21
+
22
+ public Color CurrentColor => _colorStack[^1].color;
23
+
24
+ public Material OriginalMaterial => _materialStack[0].material;
25
+
26
+ public Material CurrentMaterial => _materialStack[^1].material;
27
+
28
+ public IEnumerable<Material> Materials => _materialStack.Select(entry => entry.material);
29
+
30
+ public IEnumerable<Color> Colors => _colorStack.Select(entry => entry.color);
31
+
32
+ [SiblingComponent]
33
+ [SerializeField]
34
+ private SpriteRenderer _spriteRenderer;
35
+
36
+ private bool _enabled;
37
+
38
+ public void PushColor(Component component, Color color, bool force = false)
39
+ {
40
+ if (component == this)
41
+ {
42
+ return;
43
+ }
44
+
45
+ if (!force && !enabled)
46
+ {
47
+ return;
48
+ }
49
+
50
+ InternalPushColor(component, color);
51
+ }
52
+
53
+ private void InternalPushColor(Component component, Color color)
54
+ {
55
+ RemoveColor(component);
56
+ _colorStack.Add((component, color));
57
+ _spriteRenderer.color = CurrentColor;
58
+ }
59
+
60
+ public void PushBackColor(Component component, Color color, bool force = false)
61
+ {
62
+ if (component == this)
63
+ {
64
+ return;
65
+ }
66
+
67
+ if (!force && !enabled)
68
+ {
69
+ return;
70
+ }
71
+
72
+ RemoveColor(component);
73
+ _colorStack.Insert(1, (component, color));
74
+ _spriteRenderer.color = CurrentColor;
75
+ }
76
+
77
+ public void PopColor(Component component)
78
+ {
79
+ RemoveColor(component);
80
+ _spriteRenderer.color = CurrentColor;
81
+ }
82
+
83
+ /// <summary>
84
+ /// Inserts a material as "first in the queue".
85
+ /// </summary>
86
+ /// <param name="component">Component that owns the material.</param>
87
+ /// <param name="material">Material to use.</param>
88
+ /// <param name="force">If true, overrides the enable check.</param>
89
+ /// <returns>The instanced material, if possible.</returns>
90
+ public Material PushMaterial(Component component, Material material, bool force = false)
91
+ {
92
+ if (component == this)
93
+ {
94
+ return null;
95
+ }
96
+
97
+ if (!force && !enabled)
98
+ {
99
+ return null;
100
+ }
101
+
102
+ #if UNITY_EDITOR
103
+ if (!Application.isPlaying)
104
+ {
105
+ return null;
106
+ }
107
+ #endif
108
+ return InternalPushMaterial(component, material);
109
+ }
110
+
111
+ private Material InternalPushMaterial(Component component, Material material)
112
+ {
113
+ RemoveMaterial(component);
114
+ _spriteRenderer.material = material;
115
+ Material instanced = _spriteRenderer.material;
116
+ _materialStack.Add((component, instanced));
117
+ return instanced;
118
+ }
119
+
120
+ /// <summary>
121
+ /// Inserts a material as "last in the queue".
122
+ /// </summary>
123
+ /// <param name="component">Component that owns the material.</param>
124
+ /// <param name="material">Material to use.</param>
125
+ /// <param name="force">If true, overrides the enable check.</param>
126
+ /// <returns>The instanced material, if possible.</returns>
127
+ public Material PushBackMaterial(Component component, Material material, bool force = false)
128
+ {
129
+ if (component == this)
130
+ {
131
+ return null;
132
+ }
133
+
134
+ if (!force && !enabled)
135
+ {
136
+ return null;
137
+ }
138
+
139
+ #if UNITY_EDITOR
140
+ if (!Application.isPlaying)
141
+ {
142
+ return null;
143
+ }
144
+ #endif
145
+
146
+ RemoveMaterial(component);
147
+ Material instanced = material;
148
+ if (_materialStack.Count <= 1)
149
+ {
150
+ _spriteRenderer.material = material;
151
+ instanced = _spriteRenderer.material;
152
+ }
153
+
154
+ _materialStack.Insert(1, (component, instanced));
155
+ return instanced;
156
+ }
157
+
158
+ public void PopMaterial(Component component)
159
+ {
160
+ #if UNITY_EDITOR
161
+ if (!Application.isPlaying)
162
+ {
163
+ return;
164
+ }
165
+ #endif
166
+
167
+ RemoveMaterial(component);
168
+ _spriteRenderer.material = CurrentMaterial;
169
+ Material instanced = _spriteRenderer.material;
170
+ Component currentComponent = _materialStack[^1].component;
171
+ _materialStack[^1] = (currentComponent, instanced);
172
+ }
173
+
174
+ private void Awake()
175
+ {
176
+ if (_spriteRenderer == null)
177
+ {
178
+ this.AssignSiblingComponents();
179
+ }
180
+
181
+ InternalPushColor(this, _spriteRenderer.color);
182
+ _colorStackCache.AddRange(_colorStack);
183
+ _ = InternalPushMaterial(this, _spriteRenderer.material);
184
+ _materialStackCache.AddRange(_materialStack);
185
+ }
186
+
187
+ private void OnEnable()
188
+ {
189
+ // Ignore the OnEnable call from when the object is first initialized
190
+ if (!_enabled)
191
+ {
192
+ _enabled = true;
193
+ return;
194
+ }
195
+
196
+ _colorStack.Clear();
197
+ _colorStack.Add(_colorStackCache[0]);
198
+ List<(Component component, Color color)> colorBuffer = Buffers<(Component component, Color color)>.List;
199
+ colorBuffer.Clear();
200
+ colorBuffer.AddRange(_colorStackCache);
201
+ for (int i = 1; i < colorBuffer.Count; ++i)
202
+ {
203
+ (Component component, Color color) entry = colorBuffer[i];
204
+ PushColor(entry.component, entry.color, force: true);
205
+ }
206
+
207
+ _materialStack.Clear();
208
+ _materialStack.Add(_materialStackCache[0]);
209
+ List<(Component component, Material material)> materialBuffer =
210
+ Buffers<(Component component, Material material)>.List;
211
+ materialBuffer.Clear();
212
+ materialBuffer.AddRange(_materialStackCache);
213
+ for (int i = 1; i < materialBuffer.Count; ++i)
214
+ {
215
+ (Component component, Material material) entry = materialBuffer[i];
216
+ PushMaterial(entry.component, entry.material, force: true);
217
+ }
218
+ }
219
+
220
+ private void OnDisable()
221
+ {
222
+ List<(Component component, Color color)> colorBuffer = Buffers<(Component component, Color color)>.List;
223
+ colorBuffer.Clear();
224
+ colorBuffer.AddRange(_colorStack);
225
+ for (int i = colorBuffer.Count - 1; 1 <= i; --i)
226
+ {
227
+ PopColor(colorBuffer[i].component);
228
+ }
229
+
230
+ _colorStackCache.Clear();
231
+ _colorStackCache.AddRange(colorBuffer);
232
+
233
+ List<(Component component, Material material)> materialBuffer =
234
+ Buffers<(Component component, Material material)>.List;
235
+ materialBuffer.Clear();
236
+ materialBuffer.AddRange(_materialStack);
237
+
238
+ for (int i = materialBuffer.Count - 1; 1 <= i; --i)
239
+ {
240
+ PopMaterial(materialBuffer[i].component);
241
+ }
242
+
243
+ _materialStackCache.Clear();
244
+ _materialStackCache.AddRange(materialBuffer);
245
+ }
246
+
247
+ private void RemoveColor(Component component)
248
+ {
249
+ if (component == this)
250
+ {
251
+ return;
252
+ }
253
+
254
+ _ = _colorStack.RemoveAll(
255
+ existingComponent => existingComponent.component == component || existingComponent.component == null);
256
+ _ = _colorStackCache.RemoveAll(
257
+ existingComponent => existingComponent.component == component || existingComponent.component == null);
258
+ }
259
+
260
+ private void RemoveMaterial(Component component)
261
+ {
262
+ if (component == this)
263
+ {
264
+ return;
265
+ }
266
+
267
+ _ = _materialStack.RemoveAll(
268
+ existingComponent => existingComponent.component == component || existingComponent.component == null);
269
+ _ = _materialStackCache.RemoveAll(
270
+ existingComponent => existingComponent.component == component || existingComponent.component == null);
271
+ }
272
+ }
273
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 7b2d3d00a0e140fea968fea4859c1781
3
+ timeCreated: 1720397272