com.wallstop-studios.unity-helpers 2.0.0-rc73.18 → 2.0.0-rc73.2

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 (78) hide show
  1. package/Editor/{Sprites/AnimationCopier.cs → AnimationCopier.cs} +209 -84
  2. package/Editor/{Sprites/AnimationCreator.cs → AnimationCreator.cs} +100 -29
  3. package/Editor/AnimationEventEditor.cs +23 -10
  4. package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs +1 -1
  5. package/Editor/FitTextureSizeWindow.cs +53 -14
  6. package/Editor/PrefabChecker.cs +18 -11
  7. package/Editor/SpriteAtlasGenerator.cs +914 -0
  8. package/Editor/SpriteAtlasGenerator.cs.meta +3 -0
  9. package/Editor/{Sprites/SpriteCropper.cs → SpriteCropper.cs} +143 -172
  10. package/Editor/{Sprites/SpriteSettingsApplier.cs → SpriteSettingsApplier.cs} +77 -12
  11. package/Editor/{Sprites/TextureResizerWizard.cs → TextureResizerWizard.cs} +1 -1
  12. package/Editor/{Sprites/TextureSettingsApplier.cs → TextureSettingsApplier.cs} +1 -1
  13. package/Editor/Utils/DxReadOnlyPropertyDrawer.cs +1 -1
  14. package/Editor/Utils/GUIHorizontalScope.cs +20 -0
  15. package/Editor/Utils/GUIHorizontalScope.cs.meta +3 -0
  16. package/Runtime/Core/DataStructure/Circle.cs +1 -1
  17. package/Runtime/Core/DataStructure/QuadTree.cs +4 -4
  18. package/Runtime/Core/Extension/ColorExtensions.cs +5 -5
  19. package/Runtime/Core/Extension/IEnumerableExtensions.cs +1 -1
  20. package/Runtime/Core/Extension/UnityExtensions.cs +14 -14
  21. package/Runtime/Core/Helper/DirectoryHelper.cs +0 -64
  22. package/Runtime/Core/Helper/Helpers.cs +9 -9
  23. package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +8 -31
  24. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +4 -5
  25. package/Runtime/Core/Helper/PathHelper.cs +1 -2
  26. package/Runtime/Core/Random/DotNetRandom.cs +1 -1
  27. package/Runtime/Core/Random/SplitMix64.cs +1 -1
  28. package/Runtime/Core/Random/SquirrelRandom.cs +7 -7
  29. package/Runtime/Core/Random/ThreadLocalRandom.cs +1 -1
  30. package/Runtime/Core/Random/WyRandom.cs +1 -1
  31. package/Runtime/Tags/AttributeEffect.cs +0 -1
  32. package/Runtime/Tags/EffectHandler.cs +1 -1
  33. package/Runtime/UI/LayeredImage.cs +161 -309
  34. package/Runtime/Utils/AnimatorEnumStateMachine.cs +1 -1
  35. package/Runtime/Utils/SetTextureImportData.cs +1 -1
  36. package/Runtime/Utils/TextureScale.cs +4 -4
  37. package/Styles/Elements/{Progress/CircularProgressBar.cs → CircularProgressBar.cs} +55 -56
  38. package/Styles/Elements/{Progress/RegularProgressBar.cs → RegularProgressBar.cs} +13 -24
  39. package/Styles/UXML/CircularProgressBar.uxml +11 -0
  40. package/Styles/UXML/CircularProgressBar.uxml.meta +10 -0
  41. package/Styles/UXML/RegularProgressBar.uxml +22 -0
  42. package/Styles/UXML/RegularProgressBar.uxml.meta +10 -0
  43. package/Styles/UXML.meta +3 -0
  44. package/package.json +1 -17
  45. package/Editor/CustomEditors/PersistentDirectoryGUI.cs +0 -796
  46. package/Editor/CustomEditors/PersistentDirectoryGUI.cs.meta +0 -3
  47. package/Editor/CustomEditors/SourceFolderEntryDrawer.cs +0 -275
  48. package/Editor/CustomEditors/SourceFolderEntryDrawer.cs.meta +0 -3
  49. package/Editor/PersistentDirectorySettings.cs +0 -248
  50. package/Editor/PersistentDirectorySettings.cs.meta +0 -3
  51. package/Editor/Sprites/ScriptableSpriteAtlas.cs +0 -95
  52. package/Editor/Sprites/ScriptableSpriteAtlas.cs.meta +0 -3
  53. package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs +0 -960
  54. package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs.meta +0 -3
  55. package/Editor/Sprites.meta +0 -3
  56. package/Styles/Elements/Progress/ArcedProgressBar.cs +0 -345
  57. package/Styles/Elements/Progress/ArcedProgressBar.cs.meta +0 -3
  58. package/Styles/Elements/Progress/GlitchProgressBar.cs +0 -416
  59. package/Styles/Elements/Progress/GlitchProgressBar.cs.meta +0 -3
  60. package/Styles/Elements/Progress/LiquidProgressBar.cs +0 -632
  61. package/Styles/Elements/Progress/LiquidProgressBar.cs.meta +0 -3
  62. package/Styles/Elements/Progress/MarchingAntsProgressBar.cs +0 -722
  63. package/Styles/Elements/Progress/MarchingAntsProgressBar.cs.meta +0 -3
  64. package/Styles/Elements/Progress/WigglyProgressBar.cs +0 -837
  65. package/Styles/Elements/Progress/WigglyProgressBar.cs.meta +0 -3
  66. package/Styles/Elements/Progress.meta +0 -3
  67. package/Styles/USS/ArcedProgressBar.uss +0 -19
  68. package/Styles/USS/ArcedProgressBar.uss.meta +0 -3
  69. package/Styles/USS/WigglyProgressBar.uss +0 -17
  70. package/Styles/USS/WigglyProgressBar.uss.meta +0 -3
  71. /package/Editor/{Sprites/AnimationCopier.cs.meta → AnimationCopier.cs.meta} +0 -0
  72. /package/Editor/{Sprites/AnimationCreator.cs.meta → AnimationCreator.cs.meta} +0 -0
  73. /package/Editor/{Sprites/SpriteCropper.cs.meta → SpriteCropper.cs.meta} +0 -0
  74. /package/Editor/{Sprites/SpriteSettingsApplier.cs.meta → SpriteSettingsApplier.cs.meta} +0 -0
  75. /package/Editor/{Sprites/TextureResizerWizard.cs.meta → TextureResizerWizard.cs.meta} +0 -0
  76. /package/Editor/{Sprites/TextureSettingsApplier.cs.meta → TextureSettingsApplier.cs.meta} +0 -0
  77. /package/Styles/Elements/{Progress/CircularProgressBar.cs.meta → CircularProgressBar.cs.meta} +0 -0
  78. /package/Styles/Elements/{Progress/RegularProgressBar.cs.meta → RegularProgressBar.cs.meta} +0 -0
@@ -0,0 +1,3 @@
1
+ fileFormatVersion: 2
2
+ guid: b0dd60e3c1f24e7eb4afc773157cb996
3
+ timeCreated: 1746461513
@@ -1,4 +1,4 @@
1
- namespace WallstopStudios.UnityHelpers.Editor.Sprites
1
+ namespace WallstopStudios.UnityHelpers.Editor
2
2
  {
3
3
  #if UNITY_EDITOR
4
4
  using System;
@@ -6,10 +6,9 @@
6
6
  using System.IO;
7
7
  using System.Linq;
8
8
  using System.Threading.Tasks;
9
+ using Core.Extension;
9
10
  using UnityEditor;
10
11
  using UnityEngine;
11
- using Core.Extension;
12
- using CustomEditors;
13
12
  using Object = UnityEngine.Object;
14
13
 
15
14
  public sealed class SpriteCropper : EditorWindow
@@ -31,60 +30,25 @@
31
30
  private const float AlphaThreshold = 0.01f;
32
31
 
33
32
  [SerializeField]
34
- private List<Object> _inputDirectories = new();
33
+ private Object[] _inputDirectories;
35
34
 
36
35
  [SerializeField]
37
36
  private bool _onlyNecessary;
38
37
 
39
- [SerializeField]
40
- private int _leftPadding;
41
-
42
- [SerializeField]
43
- private int _rightPadding;
44
-
45
- [SerializeField]
46
- private int _topPadding;
47
-
48
- [SerializeField]
49
- private int _bottomPadding;
50
-
51
38
  private List<string> _filesToProcess;
52
- private SerializedObject _serializedObject;
53
- private SerializedProperty _inputDirectoriesProperty;
54
- private SerializedProperty _onlyNecessaryProperty;
55
- private SerializedProperty _leftPaddingProperty;
56
- private SerializedProperty _rightPaddingProperty;
57
- private SerializedProperty _topPaddingProperty;
58
- private SerializedProperty _bottomPaddingProperty;
59
39
 
60
40
  [MenuItem("Tools/Wallstop Studios/Unity Helpers/" + Name)]
61
41
  private static void ShowWindow() => GetWindow<SpriteCropper>(Name);
62
42
 
63
- private void OnEnable()
64
- {
65
- _serializedObject = new SerializedObject(this);
66
- _inputDirectoriesProperty = _serializedObject.FindProperty(nameof(_inputDirectories));
67
- _onlyNecessaryProperty = _serializedObject.FindProperty(nameof(_onlyNecessary));
68
- _leftPaddingProperty = _serializedObject.FindProperty(nameof(_leftPadding));
69
- _rightPaddingProperty = _serializedObject.FindProperty(nameof(_rightPadding));
70
- _topPaddingProperty = _serializedObject.FindProperty(nameof(_topPadding));
71
- _bottomPaddingProperty = _serializedObject.FindProperty(nameof(_bottomPadding));
72
- }
73
-
74
43
  private void OnGUI()
75
44
  {
76
- EditorGUILayout.LabelField("Input directories", EditorStyles.boldLabel);
77
- _serializedObject.Update();
78
- PersistentDirectoryGUI.PathSelectorObjectArray(
79
- _inputDirectoriesProperty,
80
- nameof(SpriteCropper)
81
- );
82
- EditorGUILayout.PropertyField(_onlyNecessaryProperty, true);
83
- EditorGUILayout.PropertyField(_leftPaddingProperty, true);
84
- EditorGUILayout.PropertyField(_rightPaddingProperty, true);
85
- EditorGUILayout.PropertyField(_topPaddingProperty, true);
86
- EditorGUILayout.PropertyField(_bottomPaddingProperty, true);
87
- _serializedObject.ApplyModifiedProperties();
45
+ GUILayout.Label("Drag folders below", EditorStyles.boldLabel);
46
+ SerializedObject so = new(this);
47
+ SerializedProperty dirs = so.FindProperty(nameof(_inputDirectories));
48
+ EditorGUILayout.PropertyField(dirs, true);
49
+ SerializedProperty onlyNecessary = so.FindProperty(nameof(_onlyNecessary));
50
+ EditorGUILayout.PropertyField(onlyNecessary, true);
51
+ so.ApplyModifiedProperties();
88
52
 
89
53
  if (GUILayout.Button("Find Sprites To Process"))
90
54
  {
@@ -115,7 +79,7 @@
115
79
  private void FindFilesToProcess()
116
80
  {
117
81
  _filesToProcess = new List<string>();
118
- if (_inputDirectories is not { Count: > 0 })
82
+ if (_inputDirectories == null || _inputDirectories.Length == 0)
119
83
  {
120
84
  this.LogWarn($"No input directories selected.");
121
85
  return;
@@ -154,7 +118,7 @@
154
118
 
155
119
  private void ProcessFoundSprites()
156
120
  {
157
- if (_filesToProcess is not { Count: > 0 })
121
+ if (_filesToProcess == null || _filesToProcess.Count == 0)
158
122
  {
159
123
  this.LogWarn($"No files found or selected for processing.");
160
124
  return;
@@ -205,6 +169,11 @@
205
169
  newImporters.Add(newImporter);
206
170
  }
207
171
  }
172
+
173
+ foreach (TextureImporter newImporter in newImporters)
174
+ {
175
+ newImporter.SaveAndReimport();
176
+ }
208
177
  }
209
178
  finally
210
179
  {
@@ -221,6 +190,9 @@
221
190
  $"An error occurred during processing. Last processed: {lastProcessed}.",
222
191
  e
223
192
  );
193
+ AssetDatabase.StopAssetEditing();
194
+ AssetDatabase.SaveAssets();
195
+ AssetDatabase.Refresh();
224
196
  }
225
197
  finally
226
198
  {
@@ -237,7 +209,7 @@
237
209
  }
238
210
 
239
211
  TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
240
- if (importer is not { textureType: TextureImporterType.Sprite })
212
+ if (importer == null || !importer.textureType.Equals(TextureImporterType.Sprite))
241
213
  {
242
214
  return;
243
215
  }
@@ -260,10 +232,8 @@
260
232
  return null;
261
233
  }
262
234
 
263
- if (
264
- AssetImporter.GetAtPath(assetPath)
265
- is not TextureImporter { textureType: TextureImporterType.Sprite } importer
266
- )
235
+ TextureImporter importer = AssetImporter.GetAtPath(assetPath) as TextureImporter;
236
+ if (importer == null || !importer.textureType.Equals(TextureImporterType.Sprite))
267
237
  {
268
238
  return null;
269
239
  }
@@ -271,6 +241,7 @@
271
241
  TextureImporterSettings originalSettings = new();
272
242
  importer.ReadTextureSettings(originalSettings);
273
243
 
244
+ bool originalReadableState = importer.isReadable;
274
245
  if (!importer.isReadable)
275
246
  {
276
247
  importer.isReadable = true;
@@ -283,142 +254,142 @@
283
254
  return null;
284
255
  }
285
256
 
286
- Color32[] pixels = tex.GetPixels32();
287
- int width = tex.width;
288
- int height = tex.height;
289
- int minX = width;
290
- int minY = height;
291
- int maxX = 0;
292
- int maxY = 0;
293
- bool hasVisible = false;
294
- object lockObject = new();
295
- Parallel.For(
296
- 0,
297
- width * height,
298
- () => (minX: width, minY: height, maxX: 0, maxY: 0, hasVisible: false),
299
- (index, _, localState) =>
300
- {
301
- int x = index % width;
302
- int y = index / width;
303
-
304
- float a = pixels[index].a / 255f;
305
- if (a > AlphaThreshold)
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) =>
306
277
  {
307
- localState.hasVisible = true;
308
- localState.minX = Mathf.Min(localState.minX, x);
309
- localState.minY = Mathf.Min(localState.minY, y);
310
- localState.maxX = Mathf.Max(localState.maxX, x);
311
- localState.maxY = Mathf.Max(localState.maxY, y);
312
- }
313
- return localState;
314
- },
315
- finalLocalState =>
316
- {
317
- if (finalLocalState.hasVisible)
278
+ int x = index % width;
279
+ int y = index / width;
280
+
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 =>
318
293
  {
319
- lock (lockObject)
294
+ if (finalLocalState.hasVisible)
320
295
  {
321
- hasVisible = true;
322
- minX = Mathf.Min(minX, finalLocalState.minX);
323
- minY = Mathf.Min(minY, finalLocalState.minY);
324
- maxX = Mathf.Max(maxX, finalLocalState.maxX);
325
- maxY = Mathf.Max(maxY, finalLocalState.maxY);
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
+ }
326
304
  }
327
305
  }
306
+ );
307
+
308
+ if (!hasVisible)
309
+ {
310
+ return null;
328
311
  }
329
- );
330
312
 
331
- int cropWidth;
332
- int cropHeight;
333
- if (!hasVisible)
334
- {
335
- cropWidth = 1;
336
- cropHeight = 1;
337
- minX = 0;
338
- minY = 0;
339
- }
340
- else
341
- {
342
- minX = Mathf.Max(0, minX - _leftPadding);
343
- minY = Mathf.Max(0, minY - _bottomPadding);
344
- maxX = Mathf.Min(width, maxX + _rightPadding);
345
- maxY = Mathf.Min(height, maxY + _topPadding);
346
- cropWidth = maxX - minX + 1;
347
- cropHeight = maxY - minY + 1;
348
- }
313
+ int cropWidth = maxX - minX + 1;
314
+ int cropHeight = maxY - minY + 1;
349
315
 
350
- if (_onlyNecessary && (!hasVisible || (cropWidth == width && cropHeight == height)))
351
- {
352
- return null;
353
- }
316
+ if (_onlyNecessary && cropWidth == width && cropHeight == height)
317
+ {
318
+ return null;
319
+ }
354
320
 
355
- Texture2D cropped = new(cropWidth, cropHeight, TextureFormat.RGBA32, false);
356
- Color32[] croppedPixels = new Color32[cropWidth * cropHeight];
321
+ Texture2D cropped = new(cropWidth, cropHeight, TextureFormat.RGBA32, false);
322
+ Color32[] croppedPixels = new Color32[cropWidth * cropHeight];
357
323
 
358
- Parallel.For(
359
- 0,
360
- cropHeight,
361
- y =>
362
- {
363
- int sourceYOffset = (y + minY) * width;
364
- int destYOffset = y * cropWidth;
365
- for (int x = 0; x < cropWidth; ++x)
324
+ Parallel.For(
325
+ 0,
326
+ cropHeight,
327
+ y =>
366
328
  {
367
- croppedPixels[destYOffset + x] = pixels[sourceYOffset + x + minX];
329
+ int sourceYOffset = (y + minY) * width;
330
+ int destYOffset = y * cropWidth;
331
+ for (int x = 0; x < cropWidth; ++x)
332
+ {
333
+ croppedPixels[destYOffset + x] = pixels[sourceYOffset + x + minX];
334
+ }
368
335
  }
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;
369
352
  }
370
- );
371
-
372
- cropped.SetPixels32(croppedPixels);
373
- cropped.Apply();
374
-
375
- string newPath = Path.Combine(
376
- assetDirectory,
377
- CroppedPrefix + Path.GetFileName(assetPath)
378
- );
379
- File.WriteAllBytes(newPath, cropped.EncodeToPNG());
380
- DestroyImmediate(cropped);
381
- AssetDatabase.ImportAsset(newPath);
382
- TextureImporter newImporter = AssetImporter.GetAtPath(newPath) as TextureImporter;
383
- if (newImporter == null)
384
- {
385
- return null;
386
- }
387
353
 
388
- newImporter.textureType = importer.textureType;
389
- newImporter.spriteImportMode = importer.spriteImportMode;
390
- newImporter.filterMode = importer.filterMode;
391
- newImporter.textureCompression = importer.textureCompression;
392
- newImporter.wrapMode = importer.wrapMode;
393
- newImporter.mipmapEnabled = importer.mipmapEnabled;
394
- newImporter.spritePixelsPerUnit = importer.spritePixelsPerUnit;
395
-
396
- TextureImporterSettings newSettings = new();
397
- importer.ReadTextureSettings(newSettings);
398
-
399
- Vector2 origPivot = GetSpritePivot(importer);
400
- Vector2 origCenter = new(width * origPivot.x, height * origPivot.y);
401
- Vector2 newPivotPixels = origCenter - new Vector2(minX, minY);
402
- Vector2 newPivotNorm = new(
403
- cropWidth > 0 ? newPivotPixels.x / cropWidth : 0.5f,
404
- cropHeight > 0 ? newPivotPixels.y / cropHeight : 0.5f
405
- );
406
-
407
- if (!hasVisible)
408
- {
409
- newPivotNorm = new Vector2(0.5f, 0.5f);
410
- }
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
+ );
411
373
 
412
- newImporter.spriteImportMode = SpriteImportMode.Single;
413
- newImporter.spritePivot = newPivotNorm;
414
- newSettings.spritePivot = newPivotNorm;
415
- newSettings.spriteAlignment = (int)SpriteAlignment.Custom;
374
+ newImporter.spriteImportMode = SpriteImportMode.Single;
375
+ newImporter.spritePivot = newPivotNorm;
376
+ newSettings.spritePivot = newPivotNorm;
377
+ newSettings.spriteAlignment = (int)SpriteAlignment.Custom;
416
378
 
417
- newImporter.SetTextureSettings(newSettings);
418
- newImporter.isReadable = true;
419
- newImporter.SaveAndReimport();
379
+ newImporter.SetTextureSettings(newSettings);
380
+ newImporter.isReadable = false;
381
+
382
+ resultImporter = newImporter;
383
+ }
384
+ finally
385
+ {
386
+ if (importer != null && importer.isReadable != originalReadableState)
387
+ {
388
+ importer.isReadable = originalReadableState;
389
+ importer.SaveAndReimport();
390
+ }
391
+ }
420
392
 
421
- TextureImporter resultImporter = newImporter;
422
393
  return resultImporter;
423
394
  }
424
395
 
@@ -1,16 +1,15 @@
1
1
  // ReSharper disable CompareOfFloatsByEqualityOperator
2
- namespace WallstopStudios.UnityHelpers.Editor.Sprites
2
+ namespace WallstopStudios.UnityHelpers.Editor
3
3
  {
4
4
  #if UNITY_EDITOR
5
+ using Core.Attributes;
6
+ using Core.Extension;
5
7
  using System;
6
8
  using System.Collections.Generic;
7
9
  using System.IO;
8
10
  using System.Linq;
9
11
  using UnityEditor;
10
12
  using UnityEngine;
11
- using Core.Attributes;
12
- using Core.Extension;
13
- using CustomEditors;
14
13
  using Object = UnityEngine.Object;
15
14
 
16
15
  [Serializable]
@@ -77,7 +76,7 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
77
76
  }
78
77
 
79
78
  [CustomPropertyDrawer(typeof(SpriteSettings))]
80
- public sealed class SpriteSettingsDrawer : PropertyDrawer
79
+ public class SpriteSettingsDrawer : PropertyDrawer
81
80
  {
82
81
  private const float CheckboxWidth = 18f;
83
82
  private const float HorizontalSpacing = 5f;
@@ -204,10 +203,9 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
204
203
  valuePropHeight
205
204
  );
206
205
 
207
- using (new EditorGUI.IndentLevelScope())
208
- {
209
- EditorGUI.PropertyField(valueRect, valueProp, GUIContent.none, true);
210
- }
206
+ EditorGUI.indentLevel++;
207
+ EditorGUI.PropertyField(valueRect, valueProp, GUIContent.none, true);
208
+ EditorGUI.indentLevel--;
211
209
 
212
210
  currentRect.y += valueRect.height + EditorGUIUtility.standardVerticalSpacing;
213
211
  }
@@ -301,16 +299,25 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
301
299
  private void OnGUI()
302
300
  {
303
301
  _serializedObject.Update();
302
+
304
303
  _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition);
305
304
 
306
305
  EditorGUILayout.LabelField("Sprite Sources", EditorStyles.boldLabel);
307
306
  EditorGUILayout.PropertyField(_spritesProp, new GUIContent("Specific Sprites"), true);
307
+
308
308
  EditorGUILayout.Space();
309
+
309
310
  EditorGUILayout.LabelField("Directory Sources", EditorStyles.boldLabel);
310
- PersistentDirectoryGUI.PathSelectorObjectArray(
311
+ EditorGUILayout.PropertyField(
311
312
  _directoriesProp,
312
- nameof(SpriteSettingsApplierWindow)
313
+ new GUIContent("Scan Directories"),
314
+ true
313
315
  );
316
+ if (GUILayout.Button("Add Directory via Browser"))
317
+ {
318
+ AddDirectory();
319
+ }
320
+
314
321
  EditorGUILayout.Space();
315
322
  EditorGUILayout.LabelField("Settings", EditorStyles.boldLabel);
316
323
  EditorGUILayout.PropertyField(
@@ -323,6 +330,7 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
323
330
  new GUIContent("Sprite Settings Profiles"),
324
331
  true
325
332
  );
333
+
326
334
  EditorGUILayout.Space();
327
335
  EditorGUILayout.LabelField("Actions", EditorStyles.boldLabel);
328
336
 
@@ -353,10 +361,67 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
353
361
  _serializedObject.ApplyModifiedProperties();
354
362
  }
355
363
 
364
+ private void AddDirectory()
365
+ {
366
+ string path = EditorUtility.OpenFolderPanel("Select Directory", "Assets", "");
367
+ if (string.IsNullOrWhiteSpace(path))
368
+ {
369
+ return;
370
+ }
371
+
372
+ if (path.StartsWith(Application.dataPath, StringComparison.Ordinal))
373
+ {
374
+ string relativePath = "Assets" + path.Substring(Application.dataPath.Length);
375
+ Object folderAsset = AssetDatabase.LoadAssetAtPath<Object>(relativePath);
376
+ if (folderAsset != null)
377
+ {
378
+ _directoriesProp.serializedObject.Update();
379
+ bool alreadyExists = false;
380
+ for (int i = 0; i < _directoriesProp.arraySize; i++)
381
+ {
382
+ if (
383
+ _directoriesProp.GetArrayElementAtIndex(i).objectReferenceValue
384
+ == folderAsset
385
+ )
386
+ {
387
+ alreadyExists = true;
388
+ break;
389
+ }
390
+ }
391
+
392
+ if (!alreadyExists)
393
+ {
394
+ int newIndex = _directoriesProp.arraySize;
395
+ _directoriesProp.InsertArrayElementAtIndex(newIndex);
396
+ _directoriesProp.GetArrayElementAtIndex(newIndex).objectReferenceValue =
397
+ folderAsset;
398
+ this.Log($"Added directory: {relativePath}");
399
+ }
400
+ else
401
+ {
402
+ this.LogWarn($"Directory already in list: {relativePath}");
403
+ }
404
+ _directoriesProp.serializedObject.ApplyModifiedProperties();
405
+ }
406
+ else
407
+ {
408
+ this.LogError(
409
+ $"Could not load asset at path: {relativePath}. Is it a valid folder within Assets?"
410
+ );
411
+ }
412
+ }
413
+ else
414
+ {
415
+ this.LogError(
416
+ $"Selected folder must be inside the project's Assets folder. Path selected: {path}"
417
+ );
418
+ }
419
+ }
420
+
356
421
  private List<(string fullFilePath, string relativePath)> GetTargetSpritePaths()
357
422
  {
358
423
  HashSet<string> uniqueRelativePaths = new(StringComparer.OrdinalIgnoreCase);
359
- HashSet<Object> validDirectories = new();
424
+ List<Object> validDirectories = new();
360
425
 
361
426
  for (int i = 0; i < _directoriesProp.arraySize; i++)
362
427
  {
@@ -1,4 +1,4 @@
1
- namespace WallstopStudios.UnityHelpers.Editor.Sprites
1
+ namespace WallstopStudios.UnityHelpers.Editor
2
2
  {
3
3
  #if UNITY_EDITOR
4
4
  using System;
@@ -1,4 +1,4 @@
1
- namespace WallstopStudios.UnityHelpers.Editor.Sprites
1
+ namespace WallstopStudios.UnityHelpers.Editor
2
2
  {
3
3
  #if UNITY_EDITOR
4
4
  using System;
@@ -3,7 +3,7 @@
3
3
  #if UNITY_EDITOR
4
4
  using UnityEditor;
5
5
  using UnityEngine;
6
- using Core.Attributes;
6
+ using WallstopStudios.UnityHelpers.Core.Attributes;
7
7
 
8
8
  // https://www.patrykgalach.com/2020/01/20/readonly-attribute-in-unity-editor/
9
9
  [CustomPropertyDrawer(typeof(DxReadOnlyAttribute))]
@@ -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
@@ -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(
48
+ new Bounds(
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(
56
+ new Bounds(
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(
64
+ new Bounds(
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(
72
+ new Bounds(
73
73
  new Vector3(
74
74
  boundary.center.x - halfQuadrantSize.x,
75
75
  boundary.center.y - halfQuadrantSize.y,