com.wallstop-studios.unity-helpers 2.0.0-rc05 → 2.0.0-rc07

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.
Files changed (46) hide show
  1. package/Runtime/Core/DataStructure/TimedCache.cs +4 -3
  2. package/Runtime/Core/Extension/IListExtensions.cs +2 -2
  3. package/Runtime/Core/Extension/RandomExtensions.cs +23 -4
  4. package/Runtime/Core/Extension/UnityExtensions.cs +278 -90
  5. package/Runtime/Core/Helper/ArrayConverter.cs +39 -0
  6. package/Runtime/Core/Helper/ArrayConverter.cs.meta +3 -0
  7. package/Runtime/Core/Helper/Helpers.cs +133 -563
  8. package/Runtime/Core/Helper/Partials/LogHelpers.cs +13 -0
  9. package/Runtime/Core/Helper/Partials/LogHelpers.cs.meta +3 -0
  10. package/Runtime/Core/Helper/Partials/MathHelpers.cs +30 -0
  11. package/Runtime/Core/Helper/Partials/MathHelpers.cs.meta +3 -0
  12. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +388 -0
  13. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs.meta +3 -0
  14. package/Runtime/Core/Helper/Partials/TransformHelpers.cs +167 -0
  15. package/Runtime/Core/Helper/Partials/TransformHelpers.cs.meta +3 -0
  16. package/Runtime/Core/Helper/Partials.meta +3 -0
  17. package/Runtime/Core/Helper/WallMath.cs +85 -22
  18. package/Runtime/Core/Random/AbstractRandom.cs +208 -162
  19. package/Runtime/Core/Random/DotNetRandom.cs +3 -5
  20. package/Runtime/Core/Random/PRNG.cs +7 -0
  21. package/Runtime/Core/Random/PRNG.cs.meta +3 -0
  22. package/Runtime/Core/Random/PcgRandom.cs +4 -6
  23. package/Runtime/Core/Random/RandomState.cs +31 -3
  24. package/Runtime/Core/Random/SquirrelRandom.cs +12 -15
  25. package/Runtime/Core/Random/SystemRandom.cs +92 -46
  26. package/Runtime/Core/Random/ThreadLocalRandom.cs +2 -1
  27. package/Runtime/Core/Random/UnityRandom.cs +2 -4
  28. package/Runtime/Core/Random/WyRandom.cs +2 -4
  29. package/Runtime/Core/Random/XorShiftRandom.cs +3 -5
  30. package/Runtime/Core/Serialization/Serializer.cs +36 -14
  31. package/Runtime/Utils/CircleLineRenderer.cs +17 -5
  32. package/Tests/Runtime/DataStructures/SpatialTreeTests.cs +34 -10
  33. package/Tests/Runtime/Helper/ArrayConverterTests.cs +19 -0
  34. package/Tests/Runtime/Helper/ArrayConverterTests.cs.meta +3 -0
  35. package/Tests/Runtime/Helper/ObjectHelperTests.cs +402 -0
  36. package/Tests/Runtime/Helper/ObjectHelperTests.cs.meta +3 -0
  37. package/Tests/Runtime/Helper/WallMathTests.cs +221 -0
  38. package/Tests/Runtime/Helper/WallMathTests.cs.meta +3 -0
  39. package/Tests/Runtime/Helper.meta +3 -0
  40. package/Tests/Runtime/Performance/RandomPerformanceTests.cs +58 -3
  41. package/Tests/Runtime/Performance/SpatialTreePerformanceTest.cs +47 -34
  42. package/Tests/Runtime/Random/RandomTestBase.cs +284 -9
  43. package/Tests/Runtime/Random/SquirrelRandomTests.cs +5 -0
  44. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +24 -11
  45. package/Tests/Runtime/Utils/SpriteRendererMetadataTests.cs +21 -17
  46. package/package.json +1 -1
@@ -14,7 +14,9 @@
14
14
 
15
15
  public static double BoundedDouble(double max, double value)
16
16
  {
17
- return value < max ? value : BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(value) - 1);
17
+ return value < max
18
+ ? value
19
+ : BitConverter.Int64BitsToDouble(BitConverter.DoubleToInt64Bits(value) - 1);
18
20
  }
19
21
 
20
22
  public static float BoundedFloat(float max, float value)
@@ -22,52 +24,113 @@
22
24
  return value < max
23
25
  ? value
24
26
  : BitConverter.ToSingle(
25
- BitConverter.GetBytes(BitConverter.ToInt32(BitConverter.GetBytes(value), 0) - 1), 0);
27
+ BitConverter.GetBytes(
28
+ BitConverter.ToInt32(BitConverter.GetBytes(value), 0) - 1
29
+ ),
30
+ 0
31
+ );
26
32
  }
27
33
 
28
- public static int WrappedAdd(int value, int increment, int max)
34
+ public static int WrappedAdd(this int value, int increment, int max)
29
35
  {
30
36
  WrappedAdd(ref value, increment, max);
31
37
  return value;
32
38
  }
33
39
 
34
- public static void WrappedAdd(ref int value, int increment, int max)
40
+ public static int WrappedAdd(ref int value, int increment, int max)
35
41
  {
36
- value = value + increment;
42
+ value += increment;
37
43
  if (value < max)
38
44
  {
39
- return;
45
+ return value;
40
46
  }
41
- value %= max;
47
+ return value %= max;
42
48
  }
43
49
 
44
- public static int WrappedIncrement(int value, int max)
50
+ public static int WrappedIncrement(this int value, int max)
45
51
  {
46
52
  return WrappedAdd(value, 1, max);
47
53
  }
48
54
 
49
- public static void WrappedIncrement(ref int value, int max)
55
+ public static int WrappedIncrement(ref int value, int max)
56
+ {
57
+ return WrappedAdd(ref value, 1, max);
58
+ }
59
+
60
+ public static T Clamp<T>(this T value, T min, T max)
61
+ where T : IComparable<T>
62
+ {
63
+ if (value.CompareTo(min) < 0)
64
+ {
65
+ return min;
66
+ }
67
+
68
+ return max.CompareTo(value) < 0 ? max : value;
69
+ }
70
+
71
+ public static Vector2 Clamp(this Rect bounds, Vector2 point)
50
72
  {
51
- WrappedAdd(ref value, 1, max);
73
+ return Clamp(bounds, ref point);
52
74
  }
53
75
 
54
- public static void Clamp(this Rect bounds, ref Vector2 point)
76
+ public static Vector2 Clamp(this Rect bounds, ref Vector2 point)
55
77
  {
56
- if (!bounds.Contains(point))
78
+ if (bounds.Contains(point))
79
+ {
80
+ return point;
81
+ }
82
+
83
+ Vector2 center = bounds.center;
84
+ Vector2 direction = point - center;
85
+
86
+ if (direction == Vector2.zero)
87
+ {
88
+ return center;
89
+ }
90
+
91
+ float tMax = float.MaxValue;
92
+ Vector2 min = bounds.min;
93
+ Vector2 max = bounds.max;
94
+
95
+ if (direction.x != 0)
96
+ {
97
+ if (0 < direction.x)
98
+ {
99
+ float t2 = (max.x - center.x) / direction.x;
100
+ tMax = Math.Min(tMax, t2);
101
+ }
102
+ else
103
+ {
104
+ float t1 = (min.x - center.x) / direction.x;
105
+ tMax = Math.Min(tMax, t1);
106
+ }
107
+ }
108
+
109
+ if (direction.y != 0)
57
110
  {
58
- Vector2 xClamp = bounds.width < 0 ?
59
- new Vector2(bounds.x + bounds.width, bounds.x) :
60
- new Vector2(bounds.x, bounds.x + bounds.width);
61
- Vector2 yClamp = bounds.height < 0 ?
62
- new Vector2(bounds.y + bounds.height, bounds.y) :
63
- new Vector2(bounds.y, bounds.y + bounds.height);
64
-
65
- point.x = Mathf.Clamp(point.x, xClamp.x, xClamp.y);
66
- point.y = Mathf.Clamp(point.y, yClamp.x, yClamp.y);
111
+ if (direction.y > 0)
112
+ {
113
+ float t2 = (max.y - center.y) / direction.y;
114
+ tMax = Math.Min(tMax, t2);
115
+ }
116
+ else
117
+ {
118
+ float t1 = (min.y - center.y) / direction.y;
119
+ tMax = Math.Min(tMax, t1);
120
+ }
67
121
  }
122
+
123
+ tMax = Mathf.Clamp01(tMax);
124
+
125
+ point = center + direction * tMax;
126
+ point = new Vector2(
127
+ Mathf.Clamp(point.x, min.x, max.x),
128
+ Mathf.Clamp(point.y, min.y, max.y)
129
+ );
130
+ return point;
68
131
  }
69
132
 
70
- public static bool Approximately(float lhs, float rhs, float tolerance = 0.045f)
133
+ public static bool Approximately(this float lhs, float rhs, float tolerance = 0.045f)
71
134
  {
72
135
  return Math.Abs(lhs - rhs) <= tolerance;
73
136
  }
@@ -15,25 +15,16 @@
15
15
  private static readonly ConcurrentDictionary<Type, Array> EnumTypeCache = new();
16
16
 
17
17
  protected const uint HalfwayUint = uint.MaxValue / 2;
18
- protected const double MagicDouble = 4.6566128752458E-10;
19
18
  protected const float MagicFloat = 5.960465E-008F;
20
19
 
21
20
  protected double? _cachedGaussian;
22
21
 
23
- protected AbstractRandom() { }
24
-
25
22
  public abstract RandomState InternalState { get; }
26
23
 
27
- public int Next()
24
+ public virtual int Next()
28
25
  {
29
- int result;
30
- do
31
- {
32
- result = unchecked((int)NextUint());
33
- }
34
- while (result < 0);
35
-
36
- return result;
26
+ // Mask out the MSB to ensure the value is within [0, int.MaxValue]
27
+ return unchecked((int)NextUint() & 0x7FFFFFFF);
37
28
  }
38
29
 
39
30
  public int Next(int max)
@@ -50,40 +41,136 @@
50
41
  {
51
42
  if (max <= min)
52
43
  {
53
- throw new ArgumentException($"Min {min} cannot be larger-than or equal-to max {max}");
44
+ throw new ArgumentException(
45
+ $"Min {min} cannot be larger-than or equal-to max {max}"
46
+ );
47
+ }
48
+
49
+ uint range = (uint)(max - min);
50
+ if (range == 0)
51
+ {
52
+ return unchecked((int)NextUint());
54
53
  }
55
54
 
56
- uint range = unchecked((uint)(max - min));
57
- return unchecked((int)NextUint(range)) + min;
55
+ return unchecked((int)(min + NextUint(range)));
58
56
  }
59
57
 
60
- // Internal sampler
61
- public abstract uint NextUint();
58
+ public T Next<T>(IEnumerable<T> enumerable)
59
+ {
60
+ if (enumerable is ICollection<T> collection)
61
+ {
62
+ return Next(collection);
63
+ }
62
64
 
63
- public uint NextUint(uint max)
65
+ return Next((IReadOnlyList<T>)enumerable.ToList());
66
+ }
67
+
68
+ public T Next<T>(ICollection<T> collection)
64
69
  {
65
- /*
66
- https://github.com/libevent/libevent/blob/3807a30b03ab42f2f503f2db62b1ef5876e2be80/arc4random.c#L531
70
+ int count = collection.Count;
71
+ if (count <= 0)
72
+ {
73
+ throw new ArgumentException("Collection size cannot be less-than or equal-to 0");
74
+ }
67
75
 
68
- http://cs.stackexchange.com/questions/570/generating-uniformly-distributed-random-numbers-using-a-coin
69
- Generates a uniform random number within the bound, avoiding modulo bias
70
- */
71
- uint threshold = unchecked((uint)((0x100000000UL - max) % max));
72
- while (true)
76
+ switch (collection)
73
77
  {
74
- uint randomValue = NextUint();
75
- if (threshold <= randomValue)
78
+ case IList<T> list:
79
+ return Next(list);
80
+ case IReadOnlyList<T> readOnlyList:
81
+ return Next(readOnlyList);
82
+ }
83
+
84
+ int index = Next(count);
85
+ int i = 0;
86
+ foreach (T element in collection)
87
+ {
88
+ if (i++ == index)
76
89
  {
77
- return randomValue % max;
90
+ return element;
78
91
  }
79
92
  }
93
+
94
+ // Should never happen
95
+ return default;
96
+ }
97
+
98
+ public T Next<T>(IList<T> list)
99
+ {
100
+ if (ReferenceEquals(list, null))
101
+ {
102
+ throw new ArgumentNullException(nameof(list));
103
+ }
104
+
105
+ /*
106
+ For small lists, it's much more efficient to simply return one of their elements
107
+ instead of trying to generate a random number within bounds (which is implemented as a while(true) loop)
108
+ */
109
+ switch (list.Count)
110
+ {
111
+ case 1:
112
+ return list[0];
113
+ case 2:
114
+ return NextBool() ? list[0] : list[1];
115
+ default:
116
+ return list[Next(list.Count)];
117
+ }
118
+ }
119
+
120
+ private T Next<T>(IReadOnlyList<T> list)
121
+ {
122
+ /*
123
+ For small lists, it's much more efficient to simply return one of their elements
124
+ instead of trying to generate a random number within bounds (which is implemented as a while(true) loop)
125
+ */
126
+ switch (list.Count)
127
+ {
128
+ case 1:
129
+ return list[0];
130
+ case 2:
131
+ return NextBool() ? list[0] : list[1];
132
+ default:
133
+ return list[Next(list.Count)];
134
+ }
135
+ }
136
+
137
+ public T Next<T>()
138
+ where T : struct, Enum
139
+ {
140
+ Type enumType = typeof(T);
141
+ T[] enumValues;
142
+ if (EnumTypeCache.TryGetValue(enumType, out Array enumArray))
143
+ {
144
+ enumValues = (T[])enumArray;
145
+ }
146
+ else
147
+ {
148
+ enumValues = (T[])Enum.GetValues(enumType);
149
+ }
150
+
151
+ return RandomOf(enumValues);
152
+ }
153
+
154
+ // Internal sampler
155
+ public abstract uint NextUint();
156
+
157
+ public uint NextUint(uint max)
158
+ {
159
+ if (max == 0)
160
+ {
161
+ throw new ArgumentException("Max cannot be zero");
162
+ }
163
+
164
+ return (uint)(NextDouble() * max);
80
165
  }
81
166
 
82
167
  public uint NextUint(uint min, uint max)
83
168
  {
84
169
  if (max <= min)
85
170
  {
86
- throw new ArgumentException($"Min {min} cannot be larger-than or equal-to max {max}");
171
+ throw new ArgumentException(
172
+ $"Min {min} cannot be larger-than or equal-to max {max}"
173
+ );
87
174
  }
88
175
 
89
176
  return min + NextUint(max - min);
@@ -123,12 +210,10 @@
123
210
  {
124
211
  uint upper = NextUint();
125
212
  uint lower = NextUint();
126
- // Mix things up a little
127
- if (NextBool())
213
+ unchecked
128
214
  {
129
- return unchecked((long)((ulong)upper << 32) | lower);
215
+ return (long)((((ulong)upper << 32) | lower) & (0x1UL << 63));
130
216
  }
131
- return unchecked((long)((ulong)lower << 32) | upper);
132
217
  }
133
218
 
134
219
  public long NextLong(long max)
@@ -138,51 +223,52 @@
138
223
  throw new ArgumentException($"Max {max} cannot be less-than or equal-to 0");
139
224
  }
140
225
 
141
- if (max < int.MaxValue)
142
- {
143
- return Next(unchecked((int)max));
144
- }
145
-
146
- long withinRange;
147
- do
148
- {
149
- withinRange = NextLong();
150
- }
151
- while (withinRange < 0 || max <= withinRange);
152
- return withinRange;
226
+ return (long)(NextDouble() * max);
153
227
  }
154
228
 
155
229
  public long NextLong(long min, long max)
156
230
  {
157
231
  if (max <= min)
158
232
  {
159
- throw new ArgumentException($"Min {min} cannot be larger-than or equal-to Max {max}");
233
+ throw new ArgumentException(
234
+ $"Min {min} cannot be larger-than or equal-to Max {max}"
235
+ );
160
236
  }
161
237
 
162
- return min + NextLong(max - min);
238
+ ulong range = (ulong)(max - min);
239
+ if (range == 0)
240
+ {
241
+ return unchecked((long)NextUlong());
242
+ }
243
+
244
+ return unchecked((long)(NextDouble() * range + min));
163
245
  }
164
246
 
165
247
  public ulong NextUlong()
166
248
  {
167
- return unchecked((ulong)NextLong());
249
+ uint upper = NextUint();
250
+ uint lower = NextUint();
251
+ return ((ulong)upper << 32) | lower;
168
252
  }
169
253
 
170
254
  public ulong NextUlong(ulong max)
171
255
  {
172
- return unchecked((ulong)NextLong(unchecked((long)max)));
256
+ return (ulong)(NextDouble() * max);
173
257
  }
174
258
 
175
259
  public ulong NextUlong(ulong min, ulong max)
176
260
  {
177
261
  if (max <= min)
178
262
  {
179
- throw new ArgumentException($"Min {min} cannot be larger-than or equal-to max {max}");
263
+ throw new ArgumentException(
264
+ $"Min {min} cannot be larger-than or equal-to max {max}"
265
+ );
180
266
  }
181
267
 
182
- return unchecked((ulong)NextLong(unchecked((long)min), unchecked((long)max)));
268
+ return NextUlong(max - min) + min;
183
269
  }
184
270
 
185
- public bool NextBool()
271
+ public virtual bool NextBool()
186
272
  {
187
273
  return NextUint() < HalfwayUint;
188
274
  }
@@ -194,7 +280,7 @@
194
280
  throw new ArgumentException(nameof(buffer));
195
281
  }
196
282
 
197
- const byte sizeOfInt = 4; // May differ on some platforms
283
+ const byte sizeOfInt = sizeof(int); // May differ on some platforms
198
284
 
199
285
  // See how many ints we can slap into it.
200
286
  int chunks = buffer.Length / sizeOfInt;
@@ -226,9 +312,8 @@
226
312
  double value;
227
313
  do
228
314
  {
229
- value = NextUint() * MagicDouble;
230
- }
231
- while (value < 0 || 1 <= value);
315
+ value = NextUint() * (1.0 / uint.MaxValue);
316
+ } while (1.0 <= value);
232
317
 
233
318
  return value;
234
319
  }
@@ -247,11 +332,57 @@
247
332
  {
248
333
  if (max <= min)
249
334
  {
250
- throw new ArgumentException($"Min {min} cannot be larger-than or equal-to max {max}");
335
+ throw new ArgumentException(
336
+ $"Min {min} cannot be larger-than or equal-to max {max}"
337
+ );
251
338
  }
252
339
 
253
340
  double range = max - min;
254
- return min + NextDouble(range);
341
+ if (double.IsInfinity(range))
342
+ {
343
+ return NextDoubleWithInfiniteRange(min, max);
344
+ }
345
+
346
+ return min + (NextDouble() * range);
347
+ }
348
+
349
+ protected double NextDoubleWithInfiniteRange(double min, double max)
350
+ {
351
+ double random;
352
+ do
353
+ {
354
+ random = NextDoubleFullRange();
355
+ } while (random < min || max <= random);
356
+
357
+ return random;
358
+ }
359
+
360
+ protected double NextDoubleFullRange()
361
+ {
362
+ double value = double.NaN;
363
+ do
364
+ {
365
+ ulong randomBits = NextUlong();
366
+
367
+ // Extract exponent (bits 52-62)
368
+ const ulong exponentMask = 0x7FF0000000000000;
369
+
370
+ ulong exponent = (randomBits & exponentMask) >> 52;
371
+
372
+ // Ensure exponent is not all 1's to avoid Inf and NaN
373
+ if (exponent == 0x7FF)
374
+ {
375
+ continue; // Regenerate
376
+ }
377
+
378
+ /*
379
+ For uniform distribution over all finite doubles, no further masking is necessary,
380
+ reassemble the bits
381
+ */
382
+ value = BitConverter.Int64BitsToDouble(unchecked((long)randomBits));
383
+ } while (double.IsInfinity(value) || double.IsNaN(value));
384
+
385
+ return value;
255
386
  }
256
387
 
257
388
  public double NextGaussian(double mean = 0, double stdDev = 1)
@@ -277,8 +408,7 @@
277
408
  x = 2 * NextDouble() - 1;
278
409
  y = 2 * NextDouble() - 1;
279
410
  square = x * x + y * y;
280
- }
281
- while (square > 1 || square == 0);
411
+ } while (square == 0 || 1 < square);
282
412
 
283
413
  double fac = Math.Sqrt(-2 * Math.Log(square) / square);
284
414
  _cachedGaussian = x * fac;
@@ -290,10 +420,8 @@
290
420
  float value;
291
421
  do
292
422
  {
293
- uint floatAsInt = NextUint();
294
- value = (floatAsInt >> 8) * MagicFloat;
295
- }
296
- while (value < 0 || 1 <= value);
423
+ value = NextUint() / (1f * uint.MaxValue);
424
+ } while (1f <= value);
297
425
 
298
426
  return value;
299
427
  }
@@ -312,108 +440,22 @@
312
440
  {
313
441
  if (max <= min)
314
442
  {
315
- throw new ArgumentException($"Min {min} cannot be larger-than or equal-to max {max}");
316
- }
317
-
318
- return min + NextFloat(max - min);
319
- }
320
-
321
- public T Next<T>(IEnumerable<T> enumerable)
322
- {
323
- if (enumerable is ICollection<T> collection)
324
- {
325
- return Next(collection);
326
- }
327
-
328
- return Next((IReadOnlyList<T>)enumerable.ToList());
329
- }
330
-
331
- public T Next<T>(ICollection<T> collection)
332
- {
333
- int count = collection.Count;
334
- if (count <= 0)
335
- {
336
- throw new ArgumentException("Collection size cannot be less-than or equal-to 0");
337
- }
338
-
339
- switch (collection)
340
- {
341
- case IList<T> list:
342
- return Next(list);
343
- case IReadOnlyList<T> readOnlyList:
344
- return Next(readOnlyList);
345
- }
346
-
347
- int index = Next(count);
348
- int i = 0;
349
- foreach (T element in collection)
350
- {
351
- if (i++ == index)
352
- {
353
- return element;
354
- }
355
- }
356
-
357
- // Should never happen
358
- return default;
359
- }
360
-
361
- public T Next<T>(IList<T> list)
362
- {
363
- if (ReferenceEquals(list, null))
364
- {
365
- throw new ArgumentNullException(nameof(list));
443
+ throw new ArgumentException(
444
+ $"Min {min} cannot be larger-than or equal-to max {max}"
445
+ );
366
446
  }
367
447
 
368
- /*
369
- For small lists, it's much more efficient to simply return one of their elements
370
- instead of trying to generate a random number within bounds (which is implemented as a while(true) loop)
371
- */
372
- switch (list.Count)
448
+ float range = max - min;
449
+ if (float.IsInfinity(range))
373
450
  {
374
- case 1:
375
- return list[0];
376
- case 2:
377
- return NextBool() ? list[0] : list[1];
378
- default:
379
- return list[Next(list.Count)];
451
+ return (float)NextDouble(min, max);
380
452
  }
381
- }
382
453
 
383
- private T Next<T>(IReadOnlyList<T> list)
384
- {
385
- /*
386
- For small lists, it's much more efficient to simply return one of their elements
387
- instead of trying to generate a random number within bounds (which is implemented as a while(true) loop)
388
- */
389
- switch (list.Count)
390
- {
391
- case 1:
392
- return list[0];
393
- case 2:
394
- return NextBool() ? list[0] : list[1];
395
- default:
396
- return list[Next(list.Count)];
397
- }
398
- }
399
-
400
- public T Next<T>() where T : struct, Enum
401
- {
402
- Type enumType = typeof(T);
403
- T[] enumValues;
404
- if (EnumTypeCache.TryGetValue(enumType, out Array enumArray))
405
- {
406
- enumValues = (T[])enumArray;
407
- }
408
- else
409
- {
410
- enumValues = (T[])Enum.GetValues(enumType);
411
- }
412
-
413
- return RandomOf(enumValues);
454
+ return min + NextFloat(range);
414
455
  }
415
456
 
416
- public T NextCachedEnum<T>() where T : struct, Enum
457
+ public T NextCachedEnum<T>()
458
+ where T : struct, Enum
417
459
  {
418
460
  Type enumType = typeof(T);
419
461
  T[] enumValues = (T[])EnumTypeCache.GetOrAdd(enumType, Enum.GetValues);
@@ -437,7 +479,7 @@
437
479
 
438
480
  // Advances the RNG
439
481
  // https://code2d.wordpress.com/2020/07/21/perlin-noise/
440
- public float[,] NextNoiseMap(int width, int height, float scale, int octaves)
482
+ public float[,] NextNoiseMap(int width, int height, float scale = 2.5f, int octaves = 8)
441
483
  {
442
484
  if (width <= 0)
443
485
  {
@@ -511,7 +553,11 @@
511
553
  {
512
554
  // Returns a value between 0f and 1f based on noiseMap value
513
555
  // minNoiseHeight being 0f, and maxNoiseHeight being 1f
514
- noiseMap[x, y] = Mathf.InverseLerp(minNoiseHeight, maxNoiseHeight, noiseMap[x, y]);
556
+ noiseMap[x, y] = Mathf.InverseLerp(
557
+ minNoiseHeight,
558
+ maxNoiseHeight,
559
+ noiseMap[x, y]
560
+ );
515
561
  }
516
562
  }
517
563
  return noiseMap;
@@ -534,4 +580,4 @@
534
580
 
535
581
  public abstract IRandom Copy();
536
582
  }
537
- }
583
+ }
@@ -8,8 +8,6 @@
8
8
  [DataContract]
9
9
  public sealed class DotNetRandom : AbstractRandom
10
10
  {
11
- [JsonPropertyName("State")]
12
- [DataMember(Name = "State")]
13
11
  public override RandomState InternalState =>
14
12
  new RandomState(unchecked((ulong)_seed), state2: _numberGenerated);
15
13
 
@@ -27,12 +25,12 @@
27
25
  }
28
26
 
29
27
  [JsonConstructor]
30
- public DotNetRandom(RandomState state)
28
+ public DotNetRandom(RandomState internalState)
31
29
  {
32
- _seed = unchecked((int)state.State1);
30
+ _seed = unchecked((int)internalState.State1);
33
31
  _random = new Random(_seed);
34
32
  _numberGenerated = 0;
35
- ulong generationCount = state.State2;
33
+ ulong generationCount = internalState.State2;
36
34
 
37
35
  while (_numberGenerated < generationCount)
38
36
  {
@@ -0,0 +1,7 @@
1
+ namespace UnityHelpers.Core.Random
2
+ {
3
+ public static class PRNG
4
+ {
5
+ public static IRandom Instance => PcgRandom.Instance;
6
+ }
7
+ }