com.wallstop-studios.unity-helpers 2.0.0-rc73 → 2.0.0-rc73.10

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 (63) hide show
  1. package/Editor/AnimationCopier.cs +58 -50
  2. package/Editor/AnimationCreator.cs +18 -25
  3. package/Editor/AnimationEventEditor.cs +11 -23
  4. package/Editor/FitTextureSizeWindow.cs +9 -9
  5. package/Editor/PrefabChecker.cs +14 -19
  6. package/Editor/SpriteAtlasGenerator.cs +503 -206
  7. package/Editor/SpriteCropper.cs +157 -131
  8. package/Editor/SpriteSettingsApplier.cs +5 -3
  9. package/Editor/Utils/GUIHorizontalScope.cs +20 -0
  10. package/Editor/Utils/GUIHorizontalScope.cs.meta +3 -0
  11. package/Editor/Utils/GUIIndentScope.cs +20 -0
  12. package/Editor/Utils/GUIIndentScope.cs.meta +3 -0
  13. package/Runtime/Core/DataStructure/Circle.cs +1 -1
  14. package/Runtime/Core/DataStructure/QuadTree.cs +4 -4
  15. package/Runtime/Core/Extension/ColorExtensions.cs +5 -5
  16. package/Runtime/Core/Extension/IEnumerableExtensions.cs +1 -1
  17. package/Runtime/Core/Extension/StringExtensions.cs +49 -0
  18. package/Runtime/Core/Extension/UnityExtensions.cs +14 -14
  19. package/Runtime/Core/Helper/Helpers.cs +9 -9
  20. package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +31 -8
  21. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +2 -2
  22. package/Runtime/Core/Helper/PathHelper.cs +15 -0
  23. package/Runtime/Core/Helper/PathHelper.cs.meta +3 -0
  24. package/Runtime/Core/Random/DotNetRandom.cs +1 -1
  25. package/Runtime/Core/Random/SplitMix64.cs +1 -1
  26. package/Runtime/Core/Random/SquirrelRandom.cs +7 -7
  27. package/Runtime/Core/Random/ThreadLocalRandom.cs +1 -1
  28. package/Runtime/Core/Random/WyRandom.cs +1 -1
  29. package/Runtime/Tags/AttributeEffect.cs +1 -0
  30. package/Runtime/Tags/EffectHandler.cs +1 -1
  31. package/Runtime/UI/LayeredImage.cs +309 -161
  32. package/Runtime/Utils/AnimatorEnumStateMachine.cs +1 -1
  33. package/Runtime/Utils/SetTextureImportData.cs +1 -1
  34. package/Runtime/Utils/TextureScale.cs +4 -4
  35. package/Styles/Elements/Progress/ArcedProgressBar.cs +345 -0
  36. package/Styles/Elements/Progress/ArcedProgressBar.cs.meta +3 -0
  37. package/Styles/Elements/Progress/CircularProgressBar.cs +307 -0
  38. package/Styles/Elements/Progress/CircularProgressBar.cs.meta +3 -0
  39. package/Styles/Elements/Progress/GlitchProgressBar.cs +416 -0
  40. package/Styles/Elements/Progress/GlitchProgressBar.cs.meta +3 -0
  41. package/Styles/Elements/Progress/LiquidProgressBar.cs +632 -0
  42. package/Styles/Elements/Progress/LiquidProgressBar.cs.meta +3 -0
  43. package/Styles/Elements/Progress/MarchingAntsProgressBar.cs +722 -0
  44. package/Styles/Elements/Progress/MarchingAntsProgressBar.cs.meta +3 -0
  45. package/Styles/Elements/Progress/RegularProgressBar.cs +405 -0
  46. package/Styles/Elements/Progress/RegularProgressBar.cs.meta +3 -0
  47. package/Styles/Elements/Progress/WigglyProgressBar.cs +837 -0
  48. package/Styles/Elements/Progress/WigglyProgressBar.cs.meta +3 -0
  49. package/Styles/Elements/Progress.meta +3 -0
  50. package/Styles/Elements.meta +3 -0
  51. package/Styles/USS/ArcedProgressBar.uss +19 -0
  52. package/Styles/USS/ArcedProgressBar.uss.meta +3 -0
  53. package/Styles/USS/CirclularProgressBar.uss +18 -0
  54. package/Styles/USS/CirclularProgressBar.uss.meta +3 -0
  55. package/Styles/USS/RegularProgressBar.uss +33 -0
  56. package/Styles/USS/RegularProgressBar.uss.meta +3 -0
  57. package/Styles/USS/WigglyProgressBar.uss +17 -0
  58. package/Styles/USS/WigglyProgressBar.uss.meta +3 -0
  59. package/Styles/USS.meta +3 -0
  60. package/Styles/WallstopStudios.UnityHelpers.Styles.asmdef +17 -0
  61. package/Styles/WallstopStudios.UnityHelpers.Styles.asmdef.meta +7 -0
  62. package/Styles.meta +3 -0
  63. package/package.json +11 -1
@@ -30,7 +30,7 @@
30
30
  private const float AlphaThreshold = 0.01f;
31
31
 
32
32
  [SerializeField]
33
- private Object[] _inputDirectories;
33
+ private List<Object> _inputDirectories = new();
34
34
 
35
35
  [SerializeField]
36
36
  private bool _onlyNecessary;
@@ -44,12 +44,56 @@
44
44
  {
45
45
  GUILayout.Label("Drag folders below", EditorStyles.boldLabel);
46
46
  SerializedObject so = new(this);
47
+ so.Update();
47
48
  SerializedProperty dirs = so.FindProperty(nameof(_inputDirectories));
48
49
  EditorGUILayout.PropertyField(dirs, true);
49
50
  SerializedProperty onlyNecessary = so.FindProperty(nameof(_onlyNecessary));
50
51
  EditorGUILayout.PropertyField(onlyNecessary, true);
51
52
  so.ApplyModifiedProperties();
52
53
 
54
+ if (GUILayout.Button("Select Input Folder"))
55
+ {
56
+ string path = EditorUtility.OpenFolderPanel(
57
+ "Select Sprite Input Folder",
58
+ Application.dataPath,
59
+ ""
60
+ );
61
+ if (!string.IsNullOrWhiteSpace(path))
62
+ {
63
+ if (path.StartsWith(Application.dataPath, StringComparison.Ordinal))
64
+ {
65
+ path = "Assets" + path.Substring(Application.dataPath.Length);
66
+ if (
67
+ !_inputDirectories
68
+ .Select(AssetDatabase.GetAssetPath)
69
+ .Any(directory =>
70
+ string.Equals(
71
+ directory,
72
+ path,
73
+ StringComparison.OrdinalIgnoreCase
74
+ )
75
+ )
76
+ )
77
+ {
78
+ Object folder = AssetDatabase.LoadAssetAtPath<Object>(path);
79
+ if (folder == null)
80
+ {
81
+ return;
82
+ }
83
+ _inputDirectories.Add(folder);
84
+ }
85
+ }
86
+ else
87
+ {
88
+ EditorUtility.DisplayDialog(
89
+ "Invalid Folder",
90
+ "Please select a folder inside the project's Assets directory.",
91
+ "OK"
92
+ );
93
+ }
94
+ }
95
+ }
96
+
53
97
  if (GUILayout.Button("Find Sprites To Process"))
54
98
  {
55
99
  FindFilesToProcess();
@@ -79,7 +123,7 @@
79
123
  private void FindFilesToProcess()
80
124
  {
81
125
  _filesToProcess = new List<string>();
82
- if (_inputDirectories == null || _inputDirectories.Length == 0)
126
+ if (_inputDirectories is not { Count: > 0 })
83
127
  {
84
128
  this.LogWarn($"No input directories selected.");
85
129
  return;
@@ -118,7 +162,7 @@
118
162
 
119
163
  private void ProcessFoundSprites()
120
164
  {
121
- if (_filesToProcess == null || _filesToProcess.Count == 0)
165
+ if (_filesToProcess is not { Count: > 0 })
122
166
  {
123
167
  this.LogWarn($"No files found or selected for processing.");
124
168
  return;
@@ -169,11 +213,6 @@
169
213
  newImporters.Add(newImporter);
170
214
  }
171
215
  }
172
-
173
- foreach (TextureImporter newImporter in newImporters)
174
- {
175
- newImporter.SaveAndReimport();
176
- }
177
216
  }
178
217
  finally
179
218
  {
@@ -209,7 +248,7 @@
209
248
  }
210
249
 
211
250
  TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
212
- if (importer == null || !importer.textureType.Equals(TextureImporterType.Sprite))
251
+ if (importer is not { textureType: TextureImporterType.Sprite })
213
252
  {
214
253
  return;
215
254
  }
@@ -232,8 +271,10 @@
232
271
  return null;
233
272
  }
234
273
 
235
- TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
236
- if (importer == null || !importer.textureType.Equals(TextureImporterType.Sprite))
274
+ if (
275
+ AssetImporter.GetAtPath(assetPath)
276
+ is not TextureImporter { textureType: TextureImporterType.Sprite } importer
277
+ )
237
278
  {
238
279
  return null;
239
280
  }
@@ -241,7 +282,6 @@
241
282
  TextureImporterSettings originalSettings = new();
242
283
  importer.ReadTextureSettings(originalSettings);
243
284
 
244
- bool originalReadableState = importer.isReadable;
245
285
  if (!importer.isReadable)
246
286
  {
247
287
  importer.isReadable = true;
@@ -254,142 +294,128 @@
254
294
  return null;
255
295
  }
256
296
 
257
- TextureImporter resultImporter;
258
- try
259
- {
260
- Color32[] pixels = tex.GetPixels32();
261
-
262
- int width = tex.width;
263
- int height = tex.height;
264
- int minX = width;
265
- int minY = height;
266
- int maxX = 0;
267
- int maxY = 0;
268
- bool hasVisible = false;
269
-
270
- object lockObject = new();
271
-
272
- Parallel.For(
273
- 0,
274
- width * height,
275
- () => (minX: width, minY: height, maxX: 0, maxY: 0, hasVisible: false),
276
- (index, _, localState) =>
277
- {
278
- int x = index % width;
279
- int y = index / width;
297
+ Color32[] pixels = tex.GetPixels32();
298
+ int width = tex.width;
299
+ int height = tex.height;
300
+ int minX = width;
301
+ int minY = height;
302
+ int maxX = 0;
303
+ int maxY = 0;
304
+ bool hasVisible = false;
305
+
306
+ object lockObject = new();
307
+
308
+ Parallel.For(
309
+ 0,
310
+ width * height,
311
+ () => (minX: width, minY: height, maxX: 0, maxY: 0, hasVisible: false),
312
+ (index, _, localState) =>
313
+ {
314
+ int x = index % width;
315
+ int y = index / width;
280
316
 
281
- float a = pixels[index].a / 255f;
282
- if (a > AlphaThreshold)
283
- {
284
- localState.hasVisible = true;
285
- localState.minX = Mathf.Min(localState.minX, x);
286
- localState.minY = Mathf.Min(localState.minY, y);
287
- localState.maxX = Mathf.Max(localState.maxX, x);
288
- localState.maxY = Mathf.Max(localState.maxY, y);
289
- }
290
- return localState;
291
- },
292
- finalLocalState =>
317
+ float a = pixels[index].a / 255f;
318
+ if (a > AlphaThreshold)
293
319
  {
294
- if (finalLocalState.hasVisible)
295
- {
296
- lock (lockObject)
297
- {
298
- hasVisible = true;
299
- minX = Mathf.Min(minX, finalLocalState.minX);
300
- minY = Mathf.Min(minY, finalLocalState.minY);
301
- maxX = Mathf.Max(maxX, finalLocalState.maxX);
302
- maxY = Mathf.Max(maxY, finalLocalState.maxY);
303
- }
304
- }
320
+ localState.hasVisible = true;
321
+ localState.minX = Mathf.Min(localState.minX, x);
322
+ localState.minY = Mathf.Min(localState.minY, y);
323
+ localState.maxX = Mathf.Max(localState.maxX, x);
324
+ localState.maxY = Mathf.Max(localState.maxY, y);
305
325
  }
306
- );
307
-
308
- if (!hasVisible)
309
- {
310
- return null;
311
- }
312
-
313
- int cropWidth = maxX - minX + 1;
314
- int cropHeight = maxY - minY + 1;
315
-
316
- if (_onlyNecessary && cropWidth == width && cropHeight == height)
326
+ return localState;
327
+ },
328
+ finalLocalState =>
317
329
  {
318
- return null;
319
- }
320
-
321
- Texture2D cropped = new(cropWidth, cropHeight, TextureFormat.RGBA32, false);
322
- Color32[] croppedPixels = new Color32[cropWidth * cropHeight];
323
-
324
- Parallel.For(
325
- 0,
326
- cropHeight,
327
- y =>
330
+ if (finalLocalState.hasVisible)
328
331
  {
329
- int sourceYOffset = (y + minY) * width;
330
- int destYOffset = y * cropWidth;
331
- for (int x = 0; x < cropWidth; ++x)
332
+ lock (lockObject)
332
333
  {
333
- croppedPixels[destYOffset + x] = pixels[sourceYOffset + x + minX];
334
+ hasVisible = true;
335
+ minX = Mathf.Min(minX, finalLocalState.minX);
336
+ minY = Mathf.Min(minY, finalLocalState.minY);
337
+ maxX = Mathf.Max(maxX, finalLocalState.maxX);
338
+ maxY = Mathf.Max(maxY, finalLocalState.maxY);
334
339
  }
335
340
  }
336
- );
337
-
338
- cropped.SetPixels32(croppedPixels);
339
- cropped.Apply();
340
-
341
- string newPath = Path.Combine(
342
- assetDirectory,
343
- CroppedPrefix + Path.GetFileName(assetPath)
344
- );
345
- File.WriteAllBytes(newPath, cropped.EncodeToPNG());
346
- DestroyImmediate(cropped);
347
- AssetDatabase.ImportAsset(newPath);
348
- TextureImporter newImporter = AssetImporter.GetAtPath(newPath) as TextureImporter;
349
- if (newImporter == null)
350
- {
351
- return null;
352
341
  }
342
+ );
353
343
 
354
- newImporter.textureType = importer.textureType;
355
- newImporter.spriteImportMode = importer.spriteImportMode;
356
- newImporter.filterMode = importer.filterMode;
357
- newImporter.textureCompression = importer.textureCompression;
358
- newImporter.wrapMode = importer.wrapMode;
359
- newImporter.mipmapEnabled = importer.mipmapEnabled;
360
- newImporter.spritePixelsPerUnit = importer.spritePixelsPerUnit;
361
-
362
- TextureImporterSettings newSettings = new();
363
- newImporter.ReadTextureSettings(newSettings);
364
- newSettings.spriteExtrude = originalSettings.spriteExtrude;
365
-
366
- Vector2 origPivot = GetSpritePivot(importer);
367
- Vector2 origCenter = new(width * origPivot.x, height * origPivot.y);
368
- Vector2 newPivotPixels = origCenter - new Vector2(minX, minY);
369
- Vector2 newPivotNorm = new(
370
- cropWidth > 0 ? newPivotPixels.x / cropWidth : 0.5f,
371
- cropHeight > 0 ? newPivotPixels.y / cropHeight : 0.5f
372
- );
373
-
374
- newImporter.spriteImportMode = SpriteImportMode.Single;
375
- newImporter.spritePivot = newPivotNorm;
376
- newSettings.spritePivot = newPivotNorm;
377
- newSettings.spriteAlignment = (int)SpriteAlignment.Custom;
344
+ if (!hasVisible)
345
+ {
346
+ return null;
347
+ }
378
348
 
379
- newImporter.SetTextureSettings(newSettings);
380
- newImporter.isReadable = false;
349
+ int cropWidth = maxX - minX + 1;
350
+ int cropHeight = maxY - minY + 1;
381
351
 
382
- resultImporter = newImporter;
383
- }
384
- finally
352
+ if (_onlyNecessary && cropWidth == width && cropHeight == height)
385
353
  {
386
- if (importer != null && importer.isReadable != originalReadableState)
354
+ return null;
355
+ }
356
+
357
+ Texture2D cropped = new(cropWidth, cropHeight, TextureFormat.RGBA32, false);
358
+ Color32[] croppedPixels = new Color32[cropWidth * cropHeight];
359
+
360
+ Parallel.For(
361
+ 0,
362
+ cropHeight,
363
+ y =>
387
364
  {
388
- importer.isReadable = originalReadableState;
389
- importer.SaveAndReimport();
365
+ int sourceYOffset = (y + minY) * width;
366
+ int destYOffset = y * cropWidth;
367
+ for (int x = 0; x < cropWidth; ++x)
368
+ {
369
+ croppedPixels[destYOffset + x] = pixels[sourceYOffset + x + minX];
370
+ }
390
371
  }
372
+ );
373
+
374
+ cropped.SetPixels32(croppedPixels);
375
+ cropped.Apply();
376
+
377
+ string newPath = Path.Combine(
378
+ assetDirectory,
379
+ CroppedPrefix + Path.GetFileName(assetPath)
380
+ );
381
+ File.WriteAllBytes(newPath, cropped.EncodeToPNG());
382
+ DestroyImmediate(cropped);
383
+ AssetDatabase.ImportAsset(newPath);
384
+ TextureImporter newImporter = AssetImporter.GetAtPath(newPath) as TextureImporter;
385
+ if (newImporter == null)
386
+ {
387
+ return null;
391
388
  }
392
389
 
390
+ newImporter.textureType = importer.textureType;
391
+ newImporter.spriteImportMode = importer.spriteImportMode;
392
+ newImporter.filterMode = importer.filterMode;
393
+ newImporter.textureCompression = importer.textureCompression;
394
+ newImporter.wrapMode = importer.wrapMode;
395
+ newImporter.mipmapEnabled = importer.mipmapEnabled;
396
+ newImporter.spritePixelsPerUnit = importer.spritePixelsPerUnit;
397
+
398
+ TextureImporterSettings newSettings = new();
399
+ importer.ReadTextureSettings(newSettings);
400
+
401
+ Vector2 origPivot = GetSpritePivot(importer);
402
+ Vector2 origCenter = new(width * origPivot.x, height * origPivot.y);
403
+ Vector2 newPivotPixels = origCenter - new Vector2(minX, minY);
404
+ Vector2 newPivotNorm = new(
405
+ cropWidth > 0 ? newPivotPixels.x / cropWidth : 0.5f,
406
+ cropHeight > 0 ? newPivotPixels.y / cropHeight : 0.5f
407
+ );
408
+
409
+ newImporter.spriteImportMode = SpriteImportMode.Single;
410
+ newImporter.spritePivot = newPivotNorm;
411
+ newSettings.spritePivot = newPivotNorm;
412
+ newSettings.spriteAlignment = (int)SpriteAlignment.Custom;
413
+
414
+ newImporter.SetTextureSettings(newSettings);
415
+ newImporter.isReadable = true;
416
+ newImporter.SaveAndReimport();
417
+
418
+ TextureImporter resultImporter = newImporter;
393
419
  return resultImporter;
394
420
  }
395
421
 
@@ -10,6 +10,7 @@ namespace WallstopStudios.UnityHelpers.Editor
10
10
  using System.Linq;
11
11
  using UnityEditor;
12
12
  using UnityEngine;
13
+ using Utils;
13
14
  using Object = UnityEngine.Object;
14
15
 
15
16
  [Serializable]
@@ -203,9 +204,10 @@ namespace WallstopStudios.UnityHelpers.Editor
203
204
  valuePropHeight
204
205
  );
205
206
 
206
- EditorGUI.indentLevel++;
207
- EditorGUI.PropertyField(valueRect, valueProp, GUIContent.none, true);
208
- EditorGUI.indentLevel--;
207
+ using (new GUIIndentScope())
208
+ {
209
+ EditorGUI.PropertyField(valueRect, valueProp, GUIContent.none, true);
210
+ }
209
211
 
210
212
  currentRect.y += valueRect.height + EditorGUIUtility.standardVerticalSpacing;
211
213
  }
@@ -0,0 +1,20 @@
1
+ namespace WallstopStudios.UnityHelpers.Editor.Utils
2
+ {
3
+ #if UNITY_EDITOR
4
+ using System;
5
+ using UnityEditor;
6
+
7
+ public sealed class GUIHorizontalScope : IDisposable
8
+ {
9
+ public GUIHorizontalScope()
10
+ {
11
+ EditorGUILayout.BeginHorizontal();
12
+ }
13
+
14
+ public void Dispose()
15
+ {
16
+ EditorGUILayout.EndHorizontal();
17
+ }
18
+ }
19
+ #endif
20
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: 91a6cb913d1847ae9e2a82b1f59660a7
3
+ timeCreated: 1746644886
@@ -0,0 +1,20 @@
1
+ namespace WallstopStudios.UnityHelpers.Editor.Utils
2
+ {
3
+ #if UNITY_EDITOR
4
+ using System;
5
+ using UnityEditor;
6
+
7
+ public sealed class GUIIndentScope : IDisposable
8
+ {
9
+ public GUIIndentScope()
10
+ {
11
+ EditorGUI.indentLevel++;
12
+ }
13
+
14
+ public void Dispose()
15
+ {
16
+ EditorGUI.indentLevel--;
17
+ }
18
+ }
19
+ #endif
20
+ }
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: ba7be1ee2025494c963d393c9b5e5c2f
3
+ timeCreated: 1746811930
@@ -34,7 +34,7 @@
34
34
  float yN = Math.Max(center.y, rectangle.y);
35
35
  float dX = xN - center.x;
36
36
  float dY = yN - center.y;
37
- return (dX * dX + dY * dY) <= _radiusSquared;
37
+ return dX * dX + dY * dY <= _radiusSquared;
38
38
  }
39
39
 
40
40
  public bool Overlaps(Bounds bounds)
@@ -45,7 +45,7 @@
45
45
 
46
46
  Bounds[] quadrants =
47
47
  {
48
- new Bounds(
48
+ new(
49
49
  new Vector3(
50
50
  boundary.center.x - halfQuadrantSize.x,
51
51
  boundary.center.y + halfQuadrantSize.y,
@@ -53,7 +53,7 @@
53
53
  ),
54
54
  quadrantSize
55
55
  ),
56
- new Bounds(
56
+ new(
57
57
  new Vector3(
58
58
  boundary.center.x + halfQuadrantSize.x,
59
59
  boundary.center.y + halfQuadrantSize.y,
@@ -61,7 +61,7 @@
61
61
  ),
62
62
  quadrantSize
63
63
  ),
64
- new Bounds(
64
+ new(
65
65
  new Vector3(
66
66
  boundary.center.x + halfQuadrantSize.x,
67
67
  boundary.center.y - halfQuadrantSize.y,
@@ -69,7 +69,7 @@
69
69
  ),
70
70
  quadrantSize
71
71
  ),
72
- new Bounds(
72
+ new(
73
73
  new Vector3(
74
74
  boundary.center.x - halfQuadrantSize.x,
75
75
  boundary.center.y - halfQuadrantSize.y,
@@ -534,14 +534,14 @@
534
534
  rgb.b > 0.04045 ? Mathf.Pow((rgb.b + 0.055f) / 1.055f, 2.4f) : rgb.b / 12.92f;
535
535
 
536
536
  double x = (r * 0.4124 + g * 0.3576 + b * 0.1805) / 0.95047;
537
- double y = (r * 0.2126 + g * 0.7152 + b * 0.0722);
537
+ double y = r * 0.2126 + g * 0.7152 + b * 0.0722;
538
538
  double z = (r * 0.0193 + g * 0.1192 + b * 0.9505) / 1.08883;
539
539
 
540
- x = x > 0.008856 ? Mathf.Pow((float)x, 1f / 3f) : (7.787 * x) + 16f / 116f;
541
- y = y > 0.008856 ? Mathf.Pow((float)y, 1f / 3f) : (7.787 * y) + 16f / 116f;
542
- z = z > 0.008856 ? Mathf.Pow((float)z, 1f / 3f) : (7.787 * z) + 16f / 116f;
540
+ x = x > 0.008856 ? Mathf.Pow((float)x, 1f / 3f) : 7.787 * x + 16f / 116f;
541
+ y = y > 0.008856 ? Mathf.Pow((float)y, 1f / 3f) : 7.787 * y + 16f / 116f;
542
+ z = z > 0.008856 ? Mathf.Pow((float)z, 1f / 3f) : 7.787 * z + 16f / 116f;
543
543
 
544
- return new LABColor((116 * y) - 16, 500 * (x - y), 200 * (y - z));
544
+ return new LABColor(116 * y - 16, 500 * (x - y), 200 * (y - z));
545
545
  }
546
546
 
547
547
  private static Color LABToRGB(double l, double a, double b)
@@ -78,7 +78,7 @@
78
78
 
79
79
  public static IEnumerable<IEnumerable<T>> Partition<T>(this IEnumerable<T> items, int size)
80
80
  {
81
- using var enumerator = items.GetEnumerator();
81
+ using IEnumerator<T> enumerator = items.GetEnumerator();
82
82
  bool hasNext = enumerator.MoveNext();
83
83
 
84
84
  IEnumerable<T> NextPartitionOf()
@@ -4,6 +4,7 @@
4
4
  using System.Text;
5
5
  using System.Threading;
6
6
  using Serialization;
7
+ using UnityEngine;
7
8
 
8
9
  public static class StringExtensions
9
10
  {
@@ -48,6 +49,54 @@
48
49
  return Serializer.JsonStringify(value);
49
50
  }
50
51
 
52
+ public static int LevenshteinDistance(this string source1, string source2)
53
+ {
54
+ source1 ??= string.Empty;
55
+ source2 ??= string.Empty;
56
+
57
+ int source1Length = source1.Length;
58
+ int source2Length = source2.Length;
59
+
60
+ int[][] matrix = new int[source1Length + 1][];
61
+ for (int index = 0; index < source1Length + 1; index++)
62
+ {
63
+ matrix[index] = new int[source2Length + 1];
64
+ }
65
+
66
+ if (source1Length == 0)
67
+ {
68
+ return source2Length;
69
+ }
70
+
71
+ if (source2Length == 0)
72
+ {
73
+ return source1Length;
74
+ }
75
+
76
+ for (int i = 0; i <= source1Length; matrix[i][0] = ++i)
77
+ {
78
+ // Spin to force array population
79
+ }
80
+
81
+ for (int j = 0; j <= source2Length; matrix[0][j] = ++j)
82
+ {
83
+ // Spin to force array population
84
+ }
85
+
86
+ for (int i = 1; i <= source1Length; ++i)
87
+ {
88
+ for (int j = 1; j <= source2Length; ++j)
89
+ {
90
+ int cost = source2[j - 1] == source1[i - 1] ? 0 : 1;
91
+ matrix[i][j] = Mathf.Min(
92
+ Mathf.Min(matrix[i - 1][j] + 1, matrix[i][j - 1] + 1),
93
+ matrix[i - 1][j - 1] + cost
94
+ );
95
+ }
96
+ }
97
+ return matrix[source1Length][source2Length];
98
+ }
99
+
51
100
  public static string ToPascalCase(this string value, string separator = "")
52
101
  {
53
102
  int startIndex = 0;
@@ -126,9 +126,9 @@
126
126
  xMin,
127
127
  yMin,
128
128
  zMin,
129
- (xMax - xMin) + 1,
130
- (yMax - yMin) + 1,
131
- (zMax - zMin) + 1
129
+ xMax - xMin + 1,
130
+ yMax - yMin + 1,
131
+ zMax - zMin + 1
132
132
  );
133
133
  }
134
134
 
@@ -160,9 +160,9 @@
160
160
  xMin,
161
161
  yMin,
162
162
  zMin,
163
- (xMax - xMin) + 1,
164
- (yMax - yMin) + 1,
165
- (zMax - zMin) + 1
163
+ xMax - xMin + 1,
164
+ yMax - yMin + 1,
165
+ zMax - zMin + 1
166
166
  );
167
167
  }
168
168
 
@@ -584,8 +584,8 @@
584
584
  public float LargestAngle(FastVector3Int point)
585
585
  {
586
586
  Vector2 worldPoint = _grid.CellToWorld(point);
587
- float angleFrom = Vector2.Angle((toWorld - fromWorld), (worldPoint - fromWorld));
588
- float angleTo = Vector2.Angle((fromWorld - toWorld), (worldPoint - toWorld));
587
+ float angleFrom = Vector2.Angle(toWorld - fromWorld, worldPoint - fromWorld);
588
+ float angleTo = Vector2.Angle(fromWorld - toWorld, worldPoint - toWorld);
589
589
  return Math.Max(angleFrom, angleTo);
590
590
  }
591
591
  }
@@ -1126,7 +1126,7 @@
1126
1126
  }
1127
1127
 
1128
1128
  if (
1129
- (newVector.x < position.x) == (position.x <= oldVector.x)
1129
+ newVector.x < position.x == position.x <= oldVector.x
1130
1130
  && (position.y - (long)lhs.y) * (rhs.x - lhs.x)
1131
1131
  < (rhs.y - (long)lhs.y) * (position.x - lhs.x)
1132
1132
  )
@@ -1274,7 +1274,7 @@
1274
1274
  yield break;
1275
1275
  }
1276
1276
 
1277
- scaleFactor *= (4 / 3f);
1277
+ scaleFactor *= 4 / 3f;
1278
1278
  }
1279
1279
  }
1280
1280
 
@@ -1416,8 +1416,8 @@
1416
1416
  float ty = v.y;
1417
1417
 
1418
1418
  Vector2 rotatedVector;
1419
- rotatedVector.x = (cos * tx) - (sin * ty);
1420
- rotatedVector.y = (sin * tx) + (cos * ty);
1419
+ rotatedVector.x = cos * tx - sin * ty;
1420
+ rotatedVector.y = sin * tx + cos * ty;
1421
1421
 
1422
1422
  return rotatedVector;
1423
1423
  }
@@ -1564,12 +1564,12 @@
1564
1564
 
1565
1565
  public static bool IsOnEdge2D(this FastVector3Int position, BoundsInt bounds)
1566
1566
  {
1567
- if (bounds.xMin == position.x || (bounds.xMax - 1) == position.x)
1567
+ if (bounds.xMin == position.x || bounds.xMax - 1 == position.x)
1568
1568
  {
1569
1569
  return bounds.yMin <= position.y && position.y < bounds.yMax;
1570
1570
  }
1571
1571
 
1572
- if (bounds.yMin == position.y || (bounds.yMax - 1) == position.y)
1572
+ if (bounds.yMin == position.y || bounds.yMax - 1 == position.y)
1573
1573
  {
1574
1574
  return bounds.xMin <= position.x && position.x < bounds.xMax;
1575
1575
  }