com.wallstop-studios.unity-helpers 2.0.0-rc76.2 → 2.0.0-rc76.5
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.
- package/Editor/CustomDrawers/WShowIfPropertyDrawer.cs +1 -0
- package/Editor/CustomEditors/PolygonCollider2DOptimizerEditor.cs +40 -0
- package/Editor/CustomEditors/PolygonCollider2DOptimizerEditor.cs.meta +3 -0
- package/{Runtime/Core/Extension → Editor/Extensions}/SerializedPropertyExtensions.cs +1 -1
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +29 -19
- package/Runtime/Core/Extension/DictionaryExtensions.cs +30 -10
- package/Runtime/Core/Extension/EnumExtensions.cs +4 -4
- package/Runtime/Core/Extension/IEnumerableExtensions.cs +12 -10
- package/Runtime/Core/Extension/UnityExtensions.cs +68 -0
- package/Runtime/Core/Helper/Helpers.cs +12 -0
- package/Runtime/Core/Helper/LineHelper.cs +194 -0
- package/Runtime/Core/Helper/LineHelper.cs.meta +3 -0
- package/Runtime/Tags/CollisionSenses.cs +91 -0
- package/Runtime/Tags/CollisionSenses.cs.meta +3 -0
- package/Runtime/Utils/ChildSpawner.cs +100 -0
- package/Runtime/Utils/ChildSpawner.cs.meta +3 -0
- package/Runtime/Utils/CollisionProxy.cs +48 -0
- package/Runtime/Utils/CollisionProxy.cs.meta +3 -0
- package/Runtime/Utils/PolygonCollider2DOptimizer.cs +83 -0
- package/Runtime/Utils/PolygonCollider2DOptimizer.cs.meta +3 -0
- package/Runtime/Utils/SerializedStringComparer.cs +107 -0
- package/Runtime/Utils/SerializedStringComparer.cs.meta +3 -0
- package/Tests/Runtime/DataStructures/CyclicBufferTests.cs +2 -2
- package/package.json +4 -1
- package/Editor/UI.meta +0 -3
- /package/{Runtime/Core/Extension → Editor/Extensions}/SerializedPropertyExtensions.cs.meta +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Editor.CustomEditors
|
|
2
|
+
{
|
|
3
|
+
#if UNITY_EDITOR
|
|
4
|
+
using UnityEditor;
|
|
5
|
+
using UnityEngine;
|
|
6
|
+
using UnityHelpers.Utils;
|
|
7
|
+
|
|
8
|
+
[CustomEditor(typeof(PolygonCollider2DOptimizer))]
|
|
9
|
+
public sealed class PolygonCollider2DOptimizerEditor : Editor
|
|
10
|
+
{
|
|
11
|
+
private SerializedProperty _tolerance;
|
|
12
|
+
|
|
13
|
+
private void OnEnable()
|
|
14
|
+
{
|
|
15
|
+
_tolerance = serializedObject.FindProperty(
|
|
16
|
+
nameof(PolygonCollider2DOptimizer.tolerance)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public override void OnInspectorGUI()
|
|
21
|
+
{
|
|
22
|
+
serializedObject.Update();
|
|
23
|
+
if (EditorGUILayout.PropertyField(_tolerance))
|
|
24
|
+
{
|
|
25
|
+
serializedObject.ApplyModifiedProperties();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (GUILayout.Button("Optimize"))
|
|
29
|
+
{
|
|
30
|
+
PolygonCollider2DOptimizer optimizer = target as PolygonCollider2DOptimizer;
|
|
31
|
+
if (optimizer != null)
|
|
32
|
+
{
|
|
33
|
+
optimizer.Refresh();
|
|
34
|
+
}
|
|
35
|
+
serializedObject.ApplyModifiedProperties();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
#endif
|
|
40
|
+
}
|
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
using System;
|
|
4
4
|
using System.Collections;
|
|
5
5
|
using System.Collections.Generic;
|
|
6
|
-
using System.Linq;
|
|
7
6
|
using Extension;
|
|
8
7
|
using Helper;
|
|
9
8
|
|
|
@@ -53,7 +52,6 @@
|
|
|
53
52
|
public int Count { get; private set; }
|
|
54
53
|
|
|
55
54
|
private readonly List<T> _buffer;
|
|
56
|
-
private readonly List<T> _cache;
|
|
57
55
|
private int _position;
|
|
58
56
|
|
|
59
57
|
public T this[int index]
|
|
@@ -81,7 +79,6 @@
|
|
|
81
79
|
_position = 0;
|
|
82
80
|
Count = 0;
|
|
83
81
|
_buffer = new List<T>();
|
|
84
|
-
_cache = new List<T>();
|
|
85
82
|
if (initialContents != null)
|
|
86
83
|
{
|
|
87
84
|
foreach (T item in initialContents)
|
|
@@ -131,17 +128,26 @@
|
|
|
131
128
|
|
|
132
129
|
public bool Remove(T element, IEqualityComparer<T> comparer = null)
|
|
133
130
|
{
|
|
131
|
+
if (Count == 0)
|
|
132
|
+
{
|
|
133
|
+
return false;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
int write = 0;
|
|
134
137
|
bool removed = false;
|
|
135
|
-
_cache.Clear();
|
|
136
138
|
comparer ??= EqualityComparer<T>.Default;
|
|
137
|
-
|
|
139
|
+
for (int i = 0; i < Count; ++i)
|
|
138
140
|
{
|
|
141
|
+
int readIdx = AdjustedIndexFor(i);
|
|
142
|
+
T item = _buffer[readIdx];
|
|
143
|
+
|
|
139
144
|
if (!removed && comparer.Equals(item, element))
|
|
140
145
|
{
|
|
141
146
|
removed = true;
|
|
142
147
|
continue;
|
|
143
148
|
}
|
|
144
|
-
|
|
149
|
+
|
|
150
|
+
_buffer[write++] = item;
|
|
145
151
|
}
|
|
146
152
|
|
|
147
153
|
if (!removed)
|
|
@@ -149,27 +155,34 @@
|
|
|
149
155
|
return false;
|
|
150
156
|
}
|
|
151
157
|
|
|
152
|
-
|
|
153
|
-
foreach (T item in _cache)
|
|
154
|
-
{
|
|
155
|
-
Add(item);
|
|
156
|
-
}
|
|
158
|
+
_buffer.RemoveRange(write, _buffer.Count - write);
|
|
157
159
|
|
|
160
|
+
Count--;
|
|
161
|
+
_position = Count < Capacity ? Count : 0;
|
|
158
162
|
return true;
|
|
159
163
|
}
|
|
160
164
|
|
|
161
165
|
public int RemoveAll(Func<T, bool> predicate)
|
|
162
166
|
{
|
|
167
|
+
if (Count == 0)
|
|
168
|
+
{
|
|
169
|
+
return 0;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
int write = 0;
|
|
163
173
|
int removedCount = 0;
|
|
164
|
-
|
|
174
|
+
|
|
175
|
+
for (int i = 0; i < Count; ++i)
|
|
165
176
|
{
|
|
177
|
+
int readIdx = AdjustedIndexFor(i);
|
|
178
|
+
T item = _buffer[readIdx];
|
|
166
179
|
if (predicate(item))
|
|
167
180
|
{
|
|
168
181
|
removedCount++;
|
|
169
182
|
}
|
|
170
183
|
else
|
|
171
184
|
{
|
|
172
|
-
|
|
185
|
+
_buffer[write++] = item;
|
|
173
186
|
}
|
|
174
187
|
}
|
|
175
188
|
|
|
@@ -178,12 +191,9 @@
|
|
|
178
191
|
return 0;
|
|
179
192
|
}
|
|
180
193
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
Add(item);
|
|
185
|
-
}
|
|
186
|
-
|
|
194
|
+
_buffer.RemoveRange(write, _buffer.Count - write);
|
|
195
|
+
Count -= removedCount;
|
|
196
|
+
_position = Count < Capacity ? Count : 0;
|
|
187
197
|
return removedCount;
|
|
188
198
|
}
|
|
189
199
|
|
|
@@ -144,10 +144,11 @@
|
|
|
144
144
|
|
|
145
145
|
public static Dictionary<K, V> Merge<K, V>(
|
|
146
146
|
this IReadOnlyDictionary<K, V> lhs,
|
|
147
|
-
IReadOnlyDictionary<K, V> rhs
|
|
147
|
+
IReadOnlyDictionary<K, V> rhs,
|
|
148
|
+
Func<Dictionary<K, V>> creator = null
|
|
148
149
|
)
|
|
149
150
|
{
|
|
150
|
-
Dictionary<K, V> result = new();
|
|
151
|
+
Dictionary<K, V> result = creator?.Invoke() ?? new Dictionary<K, V>();
|
|
151
152
|
if (0 < lhs.Count)
|
|
152
153
|
{
|
|
153
154
|
foreach (KeyValuePair<K, V> kvp in lhs)
|
|
@@ -176,10 +177,11 @@
|
|
|
176
177
|
/// <returns>All elements of rhs that either don't exist in or are different from lhs</returns>
|
|
177
178
|
public static Dictionary<K, V> Difference<K, V>(
|
|
178
179
|
this IReadOnlyDictionary<K, V> lhs,
|
|
179
|
-
IReadOnlyDictionary<K, V> rhs
|
|
180
|
+
IReadOnlyDictionary<K, V> rhs,
|
|
181
|
+
Func<Dictionary<K, V>> creator = null
|
|
180
182
|
)
|
|
181
183
|
{
|
|
182
|
-
Dictionary<K, V> result = new(rhs.Count);
|
|
184
|
+
Dictionary<K, V> result = creator?.Invoke() ?? new Dictionary<K, V>(rhs.Count);
|
|
183
185
|
foreach (KeyValuePair<K, V> kvp in rhs)
|
|
184
186
|
{
|
|
185
187
|
K key = kvp.Key;
|
|
@@ -194,9 +196,12 @@
|
|
|
194
196
|
return result;
|
|
195
197
|
}
|
|
196
198
|
|
|
197
|
-
public static Dictionary<V, K> Reverse<K, V>(
|
|
199
|
+
public static Dictionary<V, K> Reverse<K, V>(
|
|
200
|
+
this IReadOnlyDictionary<K, V> dictionary,
|
|
201
|
+
Func<Dictionary<V, K>> creator = null
|
|
202
|
+
)
|
|
198
203
|
{
|
|
199
|
-
Dictionary<V, K> output = new(dictionary.Count);
|
|
204
|
+
Dictionary<V, K> output = creator?.Invoke() ?? new Dictionary<V, K>(dictionary.Count);
|
|
200
205
|
foreach (KeyValuePair<K, V> entry in dictionary)
|
|
201
206
|
{
|
|
202
207
|
output[entry.Value] = entry.Key;
|
|
@@ -264,10 +269,25 @@
|
|
|
264
269
|
return false;
|
|
265
270
|
}
|
|
266
271
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
272
|
+
if (dictionary.Count != other.Count)
|
|
273
|
+
{
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (dictionary.Count == 0)
|
|
278
|
+
{
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
foreach (KeyValuePair<K, V> entry in dictionary)
|
|
283
|
+
{
|
|
284
|
+
if (!other.TryGetValue(entry.Key, out V value) || !entry.Value.Equals(value))
|
|
285
|
+
{
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
return true;
|
|
271
291
|
}
|
|
272
292
|
|
|
273
293
|
public static void Deconstruct<K, V>(this KeyValuePair<K, V> kvp, out K key, out V value)
|
|
@@ -16,8 +16,8 @@ namespace WallstopStudios.UnityHelpers.Core.Extension
|
|
|
16
16
|
|
|
17
17
|
private static readonly bool UseDensePacking;
|
|
18
18
|
private static readonly int Min;
|
|
19
|
-
private static readonly string[]
|
|
20
|
-
private static readonly Dictionary<int, string
|
|
19
|
+
private static readonly string[] DenseNames;
|
|
20
|
+
private static readonly Dictionary<int, string> SparseNames;
|
|
21
21
|
|
|
22
22
|
static EnumNameCache()
|
|
23
23
|
{
|
|
@@ -85,8 +85,8 @@ namespace WallstopStudios.UnityHelpers.Core.Extension
|
|
|
85
85
|
|
|
86
86
|
private static readonly bool UseDensePacking;
|
|
87
87
|
private static readonly int Min;
|
|
88
|
-
private static readonly string[]
|
|
89
|
-
private static readonly Dictionary<int, string
|
|
88
|
+
private static readonly string[] DenseNames;
|
|
89
|
+
private static readonly Dictionary<int, string> SparseNames;
|
|
90
90
|
|
|
91
91
|
static EnumDisplayNameCache()
|
|
92
92
|
{
|
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
FuncBasedComparer<T> comparerObject =
|
|
34
34
|
(FuncBasedComparer<T>)
|
|
35
35
|
ComparerCache.GetOrAdd(comparer, () => new FuncBasedComparer<T>(comparer));
|
|
36
|
-
return enumeration.OrderBy(
|
|
36
|
+
return enumeration.OrderBy(x => x, comparerObject);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
public static IEnumerable<T> Ordered<T>(this IEnumerable<T> enumerable)
|
|
40
40
|
where T : IComparable
|
|
41
41
|
{
|
|
42
|
-
return enumerable.OrderBy(
|
|
42
|
+
return enumerable.OrderBy(x => x);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
public static IEnumerable<T> Shuffled<T>(
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
IRandom random = null
|
|
48
48
|
)
|
|
49
49
|
{
|
|
50
|
-
random
|
|
50
|
+
random ??= ThreadLocalRandom<PcgRandom>.Instance;
|
|
51
51
|
return enumerable.OrderBy(_ => random.Next());
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -81,6 +81,13 @@
|
|
|
81
81
|
using IEnumerator<T> enumerator = items.GetEnumerator();
|
|
82
82
|
bool hasNext = enumerator.MoveNext();
|
|
83
83
|
|
|
84
|
+
while (hasNext)
|
|
85
|
+
{
|
|
86
|
+
yield return NextPartitionOf().ToList();
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
yield break;
|
|
90
|
+
|
|
84
91
|
IEnumerable<T> NextPartitionOf()
|
|
85
92
|
{
|
|
86
93
|
int remainingCountForPartition = size;
|
|
@@ -90,11 +97,6 @@
|
|
|
90
97
|
hasNext = enumerator.MoveNext();
|
|
91
98
|
}
|
|
92
99
|
}
|
|
93
|
-
|
|
94
|
-
while (hasNext)
|
|
95
|
-
{
|
|
96
|
-
yield return NextPartitionOf().ToList();
|
|
97
|
-
}
|
|
98
100
|
}
|
|
99
101
|
|
|
100
102
|
public static List<T> ToList<T>(this IEnumerable<T> enumerable, int count)
|
|
@@ -113,9 +115,9 @@
|
|
|
113
115
|
_comparer = comparer ?? throw new ArgumentNullException(nameof(comparer));
|
|
114
116
|
}
|
|
115
117
|
|
|
116
|
-
public int Compare(T
|
|
118
|
+
public int Compare(T x, T y)
|
|
117
119
|
{
|
|
118
|
-
return _comparer(
|
|
120
|
+
return _comparer(x, y);
|
|
119
121
|
}
|
|
120
122
|
}
|
|
121
123
|
}
|
|
@@ -1603,5 +1603,73 @@
|
|
|
1603
1603
|
}
|
|
1604
1604
|
}
|
|
1605
1605
|
#endif
|
|
1606
|
+
|
|
1607
|
+
public static bool IsDontDestroyOnLoad(this GameObject gameObjectToCheck)
|
|
1608
|
+
{
|
|
1609
|
+
if (gameObjectToCheck == null)
|
|
1610
|
+
{
|
|
1611
|
+
return false;
|
|
1612
|
+
}
|
|
1613
|
+
|
|
1614
|
+
return string.Equals(
|
|
1615
|
+
gameObjectToCheck.scene.name,
|
|
1616
|
+
"DontDestroyOnLoad",
|
|
1617
|
+
StringComparison.Ordinal
|
|
1618
|
+
);
|
|
1619
|
+
}
|
|
1620
|
+
|
|
1621
|
+
public static bool IsCircleFullyContained(
|
|
1622
|
+
this Collider2D targetCollider,
|
|
1623
|
+
Vector2 center,
|
|
1624
|
+
float radius,
|
|
1625
|
+
int sampleCount = 16
|
|
1626
|
+
)
|
|
1627
|
+
{
|
|
1628
|
+
for (int i = 0; i < sampleCount; ++i)
|
|
1629
|
+
{
|
|
1630
|
+
float angle = 2 * Mathf.PI / sampleCount * i;
|
|
1631
|
+
Vector2 pointOnCircle =
|
|
1632
|
+
center + new Vector2(Mathf.Cos(angle), Mathf.Sin(angle)) * radius;
|
|
1633
|
+
|
|
1634
|
+
if (!targetCollider.OverlapPoint(pointOnCircle))
|
|
1635
|
+
{
|
|
1636
|
+
return false;
|
|
1637
|
+
}
|
|
1638
|
+
}
|
|
1639
|
+
return true;
|
|
1640
|
+
}
|
|
1641
|
+
|
|
1642
|
+
public static void Invert(this PolygonCollider2D col, Rect outerRect)
|
|
1643
|
+
{
|
|
1644
|
+
int originalCount = col.pathCount;
|
|
1645
|
+
if (originalCount == 0)
|
|
1646
|
+
{
|
|
1647
|
+
return;
|
|
1648
|
+
}
|
|
1649
|
+
|
|
1650
|
+
Vector2[][] originals = new Vector2[originalCount][];
|
|
1651
|
+
for (int i = 0; i < originalCount; i++)
|
|
1652
|
+
{
|
|
1653
|
+
originals[i] = col.GetPath(i).ToArray();
|
|
1654
|
+
}
|
|
1655
|
+
|
|
1656
|
+
Vector2[] outerPath =
|
|
1657
|
+
{
|
|
1658
|
+
new Vector2(outerRect.xMin, outerRect.yMin),
|
|
1659
|
+
new Vector2(outerRect.xMin, outerRect.yMax),
|
|
1660
|
+
new Vector2(outerRect.xMax, outerRect.yMax),
|
|
1661
|
+
new Vector2(outerRect.xMax, outerRect.yMin),
|
|
1662
|
+
};
|
|
1663
|
+
|
|
1664
|
+
col.pathCount = originalCount + 1;
|
|
1665
|
+
col.SetPath(0, outerPath);
|
|
1666
|
+
|
|
1667
|
+
for (int i = 0; i < originalCount; ++i)
|
|
1668
|
+
{
|
|
1669
|
+
Vector2[] hole = originals[i];
|
|
1670
|
+
Array.Reverse(hole);
|
|
1671
|
+
col.SetPath(i + 1, hole);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1606
1674
|
}
|
|
1607
1675
|
}
|
|
@@ -13,6 +13,9 @@
|
|
|
13
13
|
using Object = UnityEngine.Object;
|
|
14
14
|
#if UNITY_EDITOR
|
|
15
15
|
using UnityEditor;
|
|
16
|
+
using UnityEditorInternal;
|
|
17
|
+
#else
|
|
18
|
+
using System;
|
|
16
19
|
#endif
|
|
17
20
|
|
|
18
21
|
public static partial class Helpers
|
|
@@ -24,6 +27,15 @@
|
|
|
24
27
|
StringComparer.Ordinal
|
|
25
28
|
);
|
|
26
29
|
|
|
30
|
+
public static string[] GetAllLayerNames()
|
|
31
|
+
{
|
|
32
|
+
#if UNITY_EDITOR
|
|
33
|
+
return InternalEditorUtility.layers;
|
|
34
|
+
#else
|
|
35
|
+
return Array.Empty<string>();
|
|
36
|
+
#endif
|
|
37
|
+
}
|
|
38
|
+
|
|
27
39
|
// https://gamedevelopment.tutsplus.com/tutorials/unity-solution-for-hitting-moving-targets--cms-29633
|
|
28
40
|
public static Vector2 PredictCurrentTarget(
|
|
29
41
|
this GameObject currentTarget,
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Core.Helper
|
|
2
|
+
{
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using System.Linq;
|
|
5
|
+
using UnityEngine;
|
|
6
|
+
|
|
7
|
+
public static class LineHelper
|
|
8
|
+
{
|
|
9
|
+
private static float PerpendicularDistance(
|
|
10
|
+
Vector2 point,
|
|
11
|
+
Vector2 lineStart,
|
|
12
|
+
Vector2 lineEnd
|
|
13
|
+
)
|
|
14
|
+
{
|
|
15
|
+
float xDistance = lineEnd.x - lineStart.x;
|
|
16
|
+
float yDistance = lineEnd.y - lineStart.y;
|
|
17
|
+
|
|
18
|
+
if (Mathf.Approximately(xDistance, 0) && Mathf.Approximately(yDistance, 0))
|
|
19
|
+
{
|
|
20
|
+
return Vector2.Distance(point, lineStart);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
float t =
|
|
24
|
+
((point.x - lineStart.x) * xDistance + (point.y - lineStart.y) * yDistance)
|
|
25
|
+
/ (xDistance * xDistance + yDistance * yDistance);
|
|
26
|
+
|
|
27
|
+
Vector2 closestPoint = t switch
|
|
28
|
+
{
|
|
29
|
+
< 0 => lineStart,
|
|
30
|
+
> 1 => lineEnd,
|
|
31
|
+
_ => new Vector2(lineStart.x + t * xDistance, lineStart.y + t * yDistance),
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return Vector2.Distance(point, closestPoint);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// c# implementation of the Ramer-Douglas-Peucker-Algorithm by Craig Selbert slightly adapted for Unity Vector Types
|
|
38
|
+
//http://www.codeproject.com/Articles/18936/A-Csharp-Implementation-of-Douglas-Peucker-Line-Ap
|
|
39
|
+
public static List<Vector2> SimplifyPrecise(List<Vector2> points, double tolerance)
|
|
40
|
+
{
|
|
41
|
+
if (points == null || points.Count < 3)
|
|
42
|
+
{
|
|
43
|
+
return points;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
int firstPoint = 0;
|
|
47
|
+
int lastPoint = points.Count - 1;
|
|
48
|
+
|
|
49
|
+
//Add the first and last index to the keepers
|
|
50
|
+
List<int> pointIndexsToKeep = new() { firstPoint, lastPoint };
|
|
51
|
+
|
|
52
|
+
//The first and the last point cannot be the same
|
|
53
|
+
while (points[firstPoint] == points[lastPoint])
|
|
54
|
+
{
|
|
55
|
+
lastPoint--;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
DouglasPeuckerReductionRecursive(
|
|
59
|
+
points,
|
|
60
|
+
firstPoint,
|
|
61
|
+
lastPoint,
|
|
62
|
+
tolerance,
|
|
63
|
+
ref pointIndexsToKeep
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
List<Vector2> returnPoints = new();
|
|
67
|
+
pointIndexsToKeep.Sort();
|
|
68
|
+
foreach (int index in pointIndexsToKeep)
|
|
69
|
+
{
|
|
70
|
+
returnPoints.Add(points[index]);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return returnPoints;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private static void DouglasPeuckerReductionRecursive(
|
|
77
|
+
List<Vector2> points,
|
|
78
|
+
int firstPoint,
|
|
79
|
+
int lastPoint,
|
|
80
|
+
double tolerance,
|
|
81
|
+
ref List<int> pointIndexesToKeep
|
|
82
|
+
)
|
|
83
|
+
{
|
|
84
|
+
while (true)
|
|
85
|
+
{
|
|
86
|
+
double maxDistance = 0;
|
|
87
|
+
int indexFarthest = 0;
|
|
88
|
+
|
|
89
|
+
for (int index = firstPoint; index < lastPoint; index++)
|
|
90
|
+
{
|
|
91
|
+
double distance = InternalPerpendicularDistance(
|
|
92
|
+
points[firstPoint],
|
|
93
|
+
points[lastPoint],
|
|
94
|
+
points[index]
|
|
95
|
+
);
|
|
96
|
+
if (distance > maxDistance)
|
|
97
|
+
{
|
|
98
|
+
maxDistance = distance;
|
|
99
|
+
indexFarthest = index;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (maxDistance > tolerance && indexFarthest != 0)
|
|
104
|
+
{
|
|
105
|
+
//Add the largest point that exceeds the tolerance
|
|
106
|
+
pointIndexesToKeep.Add(indexFarthest);
|
|
107
|
+
|
|
108
|
+
DouglasPeuckerReductionRecursive(
|
|
109
|
+
points,
|
|
110
|
+
firstPoint,
|
|
111
|
+
indexFarthest,
|
|
112
|
+
tolerance,
|
|
113
|
+
ref pointIndexesToKeep
|
|
114
|
+
);
|
|
115
|
+
|
|
116
|
+
firstPoint = indexFarthest;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return;
|
|
124
|
+
|
|
125
|
+
static double InternalPerpendicularDistance(
|
|
126
|
+
Vector2 point1,
|
|
127
|
+
Vector2 point2,
|
|
128
|
+
Vector2 point
|
|
129
|
+
)
|
|
130
|
+
{
|
|
131
|
+
double area = System.Math.Abs(
|
|
132
|
+
.5f
|
|
133
|
+
* (
|
|
134
|
+
point1.x * point2.y
|
|
135
|
+
+ point2.x * point.y
|
|
136
|
+
+ point.x * point1.y
|
|
137
|
+
- point2.x * point1.y
|
|
138
|
+
- point.x * point2.y
|
|
139
|
+
- point1.x * point.y
|
|
140
|
+
)
|
|
141
|
+
);
|
|
142
|
+
double bottom = System.Math.Sqrt(
|
|
143
|
+
System.Math.Pow(point1.x - point2.x, 2.0)
|
|
144
|
+
+ System.Math.Pow(point1.y - point2.y, 2.0)
|
|
145
|
+
);
|
|
146
|
+
double height = area / bottom * 2.0;
|
|
147
|
+
return height;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public static List<Vector2> Simplify(List<Vector2> points, float epsilon)
|
|
152
|
+
{
|
|
153
|
+
if (points == null || points.Count < 3 || epsilon <= 0)
|
|
154
|
+
{
|
|
155
|
+
return new List<Vector2>(points ?? Enumerable.Empty<Vector2>());
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
float maxDistance = 0;
|
|
159
|
+
int index = 0;
|
|
160
|
+
int end = points.Count - 1;
|
|
161
|
+
|
|
162
|
+
for (int i = 1; i < end; ++i)
|
|
163
|
+
{
|
|
164
|
+
float distance = PerpendicularDistance(points[i], points[0], points[end]);
|
|
165
|
+
if (distance > maxDistance)
|
|
166
|
+
{
|
|
167
|
+
index = i;
|
|
168
|
+
maxDistance = distance;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
List<Vector2> result = new();
|
|
173
|
+
|
|
174
|
+
if (maxDistance > epsilon)
|
|
175
|
+
{
|
|
176
|
+
List<Vector2> recResults1 = Simplify(points.GetRange(0, index + 1), epsilon);
|
|
177
|
+
List<Vector2> recResults2 = Simplify(
|
|
178
|
+
points.GetRange(index, points.Count - index),
|
|
179
|
+
epsilon
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
result.AddRange(recResults1.Take(recResults1.Count - 1));
|
|
183
|
+
result.AddRange(recResults2);
|
|
184
|
+
}
|
|
185
|
+
else
|
|
186
|
+
{
|
|
187
|
+
result.Add(points[0]);
|
|
188
|
+
result.Add(points[end]);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
return result;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Tags
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using Core.Attributes;
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
|
|
8
|
+
[DisallowMultipleComponent]
|
|
9
|
+
[RequireComponent(typeof(TagHandler))]
|
|
10
|
+
public sealed class CollisionSenses : MonoBehaviour
|
|
11
|
+
{
|
|
12
|
+
public const string CollisionDisabledTag = nameof(CollisionDisabledTag);
|
|
13
|
+
|
|
14
|
+
[SiblingComponent]
|
|
15
|
+
private TagHandler _tagHandler;
|
|
16
|
+
|
|
17
|
+
private readonly List<Collider2D> _managedColliders = new();
|
|
18
|
+
|
|
19
|
+
private void Awake()
|
|
20
|
+
{
|
|
21
|
+
this.AssignRelationalComponents();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
private void OnEnable()
|
|
25
|
+
{
|
|
26
|
+
if (_tagHandler.HasTag(CollisionDisabledTag))
|
|
27
|
+
{
|
|
28
|
+
StartManagingColliders();
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
_tagHandler.OnTagAdded += CheckForTagAddition;
|
|
32
|
+
_tagHandler.OnTagRemoved += CheckForTagRemoval;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
private void OnDisable()
|
|
36
|
+
{
|
|
37
|
+
_tagHandler.OnTagAdded -= CheckForTagAddition;
|
|
38
|
+
_tagHandler.OnTagRemoved -= CheckForTagRemoval;
|
|
39
|
+
StopManagingColliders();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
private void CheckForTagAddition(string addedTag)
|
|
43
|
+
{
|
|
44
|
+
if (!isActiveAndEnabled)
|
|
45
|
+
{
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (string.Equals(addedTag, CollisionDisabledTag, StringComparison.Ordinal))
|
|
50
|
+
{
|
|
51
|
+
StartManagingColliders();
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private void CheckForTagRemoval(string removedTag)
|
|
56
|
+
{
|
|
57
|
+
if (!isActiveAndEnabled)
|
|
58
|
+
{
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (string.Equals(removedTag, CollisionDisabledTag, StringComparison.Ordinal))
|
|
63
|
+
{
|
|
64
|
+
StopManagingColliders();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
private void StopManagingColliders()
|
|
69
|
+
{
|
|
70
|
+
foreach (Collider2D managedCollider in _managedColliders)
|
|
71
|
+
{
|
|
72
|
+
if (managedCollider != null)
|
|
73
|
+
{
|
|
74
|
+
managedCollider.enabled = true;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
_managedColliders.Clear();
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private void StartManagingColliders()
|
|
82
|
+
{
|
|
83
|
+
GetComponentsInChildren(_managedColliders);
|
|
84
|
+
_managedColliders.RemoveAll(managed => !managed.enabled);
|
|
85
|
+
foreach (Collider2D managedCollider in _managedColliders)
|
|
86
|
+
{
|
|
87
|
+
managedCollider.enabled = false;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Utils
|
|
2
|
+
{
|
|
3
|
+
using System.Collections.Generic;
|
|
4
|
+
using System.Linq;
|
|
5
|
+
using Core.Extension;
|
|
6
|
+
using UnityEngine;
|
|
7
|
+
|
|
8
|
+
[DisallowMultipleComponent]
|
|
9
|
+
public sealed class ChildSpawner : MonoBehaviour
|
|
10
|
+
{
|
|
11
|
+
private static readonly HashSet<GameObject> SpawnedPrefabs = new();
|
|
12
|
+
|
|
13
|
+
[SerializeField]
|
|
14
|
+
private GameObject[] _prefabs;
|
|
15
|
+
|
|
16
|
+
[SerializeField]
|
|
17
|
+
private GameObject[] _editorOnlyPrefabs;
|
|
18
|
+
|
|
19
|
+
[SerializeField]
|
|
20
|
+
private GameObject[] _developmentOnlyPrefabs;
|
|
21
|
+
|
|
22
|
+
private void Start()
|
|
23
|
+
{
|
|
24
|
+
if (
|
|
25
|
+
_prefabs
|
|
26
|
+
.Concat(_editorOnlyPrefabs)
|
|
27
|
+
.Concat(_developmentOnlyPrefabs)
|
|
28
|
+
.Distinct()
|
|
29
|
+
.Count()
|
|
30
|
+
!= (_prefabs.Length + _editorOnlyPrefabs.Length + _developmentOnlyPrefabs.Length)
|
|
31
|
+
)
|
|
32
|
+
{
|
|
33
|
+
IEnumerable<string> duplicateChildNames = _prefabs
|
|
34
|
+
.Concat(_editorOnlyPrefabs)
|
|
35
|
+
.Concat(_developmentOnlyPrefabs)
|
|
36
|
+
.GroupBy(x => x)
|
|
37
|
+
.Where(group => group.Count() > 1)
|
|
38
|
+
.Select(group => group.Key != null ? group.Key.name : "null");
|
|
39
|
+
this.LogError(
|
|
40
|
+
$"Duplicate child prefab detected: {string.Join(",", duplicateChildNames)}"
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
int count = 0;
|
|
45
|
+
foreach (GameObject prefab in _prefabs)
|
|
46
|
+
{
|
|
47
|
+
GameObject child = Spawn(prefab);
|
|
48
|
+
if (child != null)
|
|
49
|
+
{
|
|
50
|
+
child.name = $"{child.name} ({count++:00})";
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (Application.isEditor)
|
|
55
|
+
{
|
|
56
|
+
foreach (GameObject prefab in _editorOnlyPrefabs)
|
|
57
|
+
{
|
|
58
|
+
GameObject child = Spawn(prefab);
|
|
59
|
+
if (child != null)
|
|
60
|
+
{
|
|
61
|
+
child.name = $"{child.name} (EDITOR-ONLY {count++:00})";
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (Application.isEditor || Debug.isDebugBuild)
|
|
67
|
+
{
|
|
68
|
+
foreach (GameObject prefab in _developmentOnlyPrefabs)
|
|
69
|
+
{
|
|
70
|
+
GameObject child = Spawn(prefab);
|
|
71
|
+
if (child != null)
|
|
72
|
+
{
|
|
73
|
+
child.name = $"{child.name} (DEVELOPMENT-ONLY {count++:00})";
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private static void CleanName(GameObject child)
|
|
80
|
+
{
|
|
81
|
+
child.name = child.name.Replace("(Clone)", string.Empty);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
private GameObject Spawn(GameObject prefab)
|
|
85
|
+
{
|
|
86
|
+
if (SpawnedPrefabs.Contains(prefab))
|
|
87
|
+
{
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
GameObject child = Instantiate(prefab, transform);
|
|
92
|
+
CleanName(child);
|
|
93
|
+
if (child.IsDontDestroyOnLoad() || gameObject.IsDontDestroyOnLoad())
|
|
94
|
+
{
|
|
95
|
+
SpawnedPrefabs.Add(prefab);
|
|
96
|
+
}
|
|
97
|
+
return child;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Utils
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using UnityEngine;
|
|
5
|
+
|
|
6
|
+
[DisallowMultipleComponent]
|
|
7
|
+
[RequireComponent(typeof(Collider2D))]
|
|
8
|
+
public sealed class CollisionProxy : MonoBehaviour
|
|
9
|
+
{
|
|
10
|
+
public event Action<Collision2D> OnCollisionEnter = _ => { };
|
|
11
|
+
public event Action<Collision2D> OnCollisionStay = _ => { };
|
|
12
|
+
public event Action<Collision2D> OnCollisionExit = _ => { };
|
|
13
|
+
|
|
14
|
+
public event Action<Collider2D> OnTriggerEnter = _ => { };
|
|
15
|
+
public event Action<Collider2D> OnTriggerStay = _ => { };
|
|
16
|
+
public event Action<Collider2D> OnTriggerExit = _ => { };
|
|
17
|
+
|
|
18
|
+
private void OnTriggerEnter2D(Collider2D other)
|
|
19
|
+
{
|
|
20
|
+
OnTriggerEnter?.Invoke(other);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
private void OnTriggerStay2D(Collider2D other)
|
|
24
|
+
{
|
|
25
|
+
OnTriggerStay?.Invoke(other);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private void OnTriggerExit2D(Collider2D other)
|
|
29
|
+
{
|
|
30
|
+
OnTriggerExit?.Invoke(other);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
private void OnCollisionEnter2D(Collision2D other)
|
|
34
|
+
{
|
|
35
|
+
OnCollisionEnter?.Invoke(other);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private void OnCollisionStay2D(Collision2D other)
|
|
39
|
+
{
|
|
40
|
+
OnCollisionStay?.Invoke(other);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private void OnCollisionExit2D(Collision2D other)
|
|
44
|
+
{
|
|
45
|
+
OnCollisionExit?.Invoke(other);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Utils
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using Core.Attributes;
|
|
6
|
+
using Core.Helper;
|
|
7
|
+
using UnityEngine;
|
|
8
|
+
|
|
9
|
+
/// <summary>
|
|
10
|
+
/// Polygon collider optimizer. Removes points from the collider polygon with
|
|
11
|
+
/// the given reduction Tolerance
|
|
12
|
+
/// </summary>
|
|
13
|
+
[AddComponentMenu("2D Collider Optimization/ Polygon Collider Optimizer")]
|
|
14
|
+
[RequireComponent(typeof(PolygonCollider2D))]
|
|
15
|
+
public sealed class PolygonCollider2DOptimizer : MonoBehaviour
|
|
16
|
+
{
|
|
17
|
+
[Serializable]
|
|
18
|
+
private sealed class Path
|
|
19
|
+
{
|
|
20
|
+
public List<Vector2> points = new();
|
|
21
|
+
|
|
22
|
+
public Path() { }
|
|
23
|
+
|
|
24
|
+
public Path(IEnumerable<Vector2> points)
|
|
25
|
+
{
|
|
26
|
+
this.points.AddRange(points);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
public double tolerance;
|
|
31
|
+
|
|
32
|
+
[SiblingComponent]
|
|
33
|
+
private PolygonCollider2D _collider;
|
|
34
|
+
|
|
35
|
+
[SerializeField]
|
|
36
|
+
private List<Path> _originalPaths = new();
|
|
37
|
+
|
|
38
|
+
public void Refresh()
|
|
39
|
+
{
|
|
40
|
+
OnValidate();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
private void OnValidate()
|
|
44
|
+
{
|
|
45
|
+
if (_collider == null)
|
|
46
|
+
{
|
|
47
|
+
this.AssignRelationalComponents();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/*
|
|
51
|
+
When first getting a reference to the collider save the paths
|
|
52
|
+
so that the optimization is re-doable (by performing it on the original path
|
|
53
|
+
every time)
|
|
54
|
+
*/
|
|
55
|
+
if (_originalPaths.Count == 0)
|
|
56
|
+
{
|
|
57
|
+
for (int i = 0; i < _collider.pathCount; ++i)
|
|
58
|
+
{
|
|
59
|
+
List<Vector2> points = new(_collider.GetPath(i));
|
|
60
|
+
Path path = new(points);
|
|
61
|
+
_originalPaths.Add(path);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//Reset the original paths
|
|
66
|
+
if (tolerance <= 0)
|
|
67
|
+
{
|
|
68
|
+
for (int i = 0; i < _originalPaths.Count; ++i)
|
|
69
|
+
{
|
|
70
|
+
_collider.SetPath(i, _originalPaths[i].points.ToArray());
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
for (int i = 0; i < _originalPaths.Count; ++i)
|
|
76
|
+
{
|
|
77
|
+
List<Vector2> path = _originalPaths[i].points;
|
|
78
|
+
List<Vector2> updatedPath = LineHelper.SimplifyPrecise(path, tolerance);
|
|
79
|
+
_collider.SetPath(i, updatedPath.ToArray());
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Utils
|
|
2
|
+
{
|
|
3
|
+
using System;
|
|
4
|
+
using System.Collections.Generic;
|
|
5
|
+
using System.ComponentModel;
|
|
6
|
+
|
|
7
|
+
[Serializable]
|
|
8
|
+
public sealed class SerializedStringComparer : IEqualityComparer<string>
|
|
9
|
+
{
|
|
10
|
+
public enum StringCompareMode
|
|
11
|
+
{
|
|
12
|
+
Ordinal = 0,
|
|
13
|
+
OrdinalIgnoreCase = 1,
|
|
14
|
+
CurrentCulture = 2,
|
|
15
|
+
CurrentCultureIgnoreCase = 3,
|
|
16
|
+
InvariantCulture = 4,
|
|
17
|
+
InvariantCultureIgnoreCase = 5,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public StringCompareMode compareMode = StringCompareMode.Ordinal;
|
|
21
|
+
|
|
22
|
+
public SerializedStringComparer() { }
|
|
23
|
+
|
|
24
|
+
public SerializedStringComparer(StringCompareMode compareMode)
|
|
25
|
+
{
|
|
26
|
+
this.compareMode = compareMode;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
public bool Equals(string x, string y)
|
|
30
|
+
{
|
|
31
|
+
switch (compareMode)
|
|
32
|
+
{
|
|
33
|
+
case StringCompareMode.Ordinal:
|
|
34
|
+
{
|
|
35
|
+
return StringComparer.Ordinal.Equals(x, y);
|
|
36
|
+
}
|
|
37
|
+
case StringCompareMode.OrdinalIgnoreCase:
|
|
38
|
+
{
|
|
39
|
+
return StringComparer.OrdinalIgnoreCase.Equals(x, y);
|
|
40
|
+
}
|
|
41
|
+
case StringCompareMode.CurrentCulture:
|
|
42
|
+
{
|
|
43
|
+
return StringComparer.CurrentCulture.Equals(x, y);
|
|
44
|
+
}
|
|
45
|
+
case StringCompareMode.CurrentCultureIgnoreCase:
|
|
46
|
+
{
|
|
47
|
+
return StringComparer.CurrentCultureIgnoreCase.Equals(x, y);
|
|
48
|
+
}
|
|
49
|
+
case StringCompareMode.InvariantCulture:
|
|
50
|
+
{
|
|
51
|
+
return StringComparer.InvariantCulture.Equals(x, y);
|
|
52
|
+
}
|
|
53
|
+
case StringCompareMode.InvariantCultureIgnoreCase:
|
|
54
|
+
{
|
|
55
|
+
return StringComparer.InvariantCultureIgnoreCase.Equals(x, y);
|
|
56
|
+
}
|
|
57
|
+
default:
|
|
58
|
+
{
|
|
59
|
+
throw new InvalidEnumArgumentException(
|
|
60
|
+
nameof(compareMode),
|
|
61
|
+
(int)compareMode,
|
|
62
|
+
typeof(StringCompareMode)
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
public int GetHashCode(string obj)
|
|
69
|
+
{
|
|
70
|
+
switch (compareMode)
|
|
71
|
+
{
|
|
72
|
+
case StringCompareMode.Ordinal:
|
|
73
|
+
{
|
|
74
|
+
return StringComparer.Ordinal.GetHashCode(obj);
|
|
75
|
+
}
|
|
76
|
+
case StringCompareMode.OrdinalIgnoreCase:
|
|
77
|
+
{
|
|
78
|
+
return StringComparer.OrdinalIgnoreCase.GetHashCode(obj);
|
|
79
|
+
}
|
|
80
|
+
case StringCompareMode.CurrentCulture:
|
|
81
|
+
{
|
|
82
|
+
return StringComparer.CurrentCulture.GetHashCode(obj);
|
|
83
|
+
}
|
|
84
|
+
case StringCompareMode.CurrentCultureIgnoreCase:
|
|
85
|
+
{
|
|
86
|
+
return StringComparer.CurrentCultureIgnoreCase.GetHashCode(obj);
|
|
87
|
+
}
|
|
88
|
+
case StringCompareMode.InvariantCulture:
|
|
89
|
+
{
|
|
90
|
+
return StringComparer.InvariantCulture.GetHashCode(obj);
|
|
91
|
+
}
|
|
92
|
+
case StringCompareMode.InvariantCultureIgnoreCase:
|
|
93
|
+
{
|
|
94
|
+
return StringComparer.InvariantCultureIgnoreCase.GetHashCode(obj);
|
|
95
|
+
}
|
|
96
|
+
default:
|
|
97
|
+
{
|
|
98
|
+
throw new InvalidEnumArgumentException(
|
|
99
|
+
nameof(compareMode),
|
|
100
|
+
(int)compareMode,
|
|
101
|
+
typeof(StringCompareMode)
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
Assert.Throws<ArgumentException>(() => new CyclicBuffer<int>(int.MinValue));
|
|
20
20
|
for (int i = 0; i < NumTries; i++)
|
|
21
21
|
{
|
|
22
|
-
Assert.Throws<ArgumentException>(
|
|
23
|
-
|
|
22
|
+
Assert.Throws<ArgumentException>(() =>
|
|
23
|
+
new CyclicBuffer<int>(PRNG.Instance.Next(int.MinValue, -1))
|
|
24
24
|
);
|
|
25
25
|
}
|
|
26
26
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "com.wallstop-studios.unity-helpers",
|
|
3
|
-
"version": "2.0.0-rc76.
|
|
3
|
+
"version": "2.0.0-rc76.5",
|
|
4
4
|
"displayName": "Unity Helpers",
|
|
5
5
|
"description": "Various Unity Helper Library",
|
|
6
6
|
"dependencies": {},
|
|
@@ -74,6 +74,9 @@
|
|
|
74
74
|
|
|
75
75
|
|
|
76
76
|
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
|
|
77
80
|
|
|
78
81
|
|
|
79
82
|
|
package/Editor/UI.meta
DELETED
|
File without changes
|