com.wallstop-studios.unity-helpers 2.0.0-rc81.9 → 2.0.0

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 (168) hide show
  1. package/.editorconfig +1 -1
  2. package/.gitattributes +1 -1
  3. package/.githooks/pre-commit +31 -5
  4. package/.githooks/pre-push +50 -0
  5. package/.github/dependabot.yml +24 -2
  6. package/.github/scripts/check-markdown-links.ps1 +77 -0
  7. package/.github/scripts/check_markdown_links.py +89 -0
  8. package/.github/scripts/check_markdown_url_encoding.py +74 -0
  9. package/.github/scripts/validate_markdown_links.py +194 -0
  10. package/.github/workflows/csharpier-autofix.yml +152 -0
  11. package/.github/workflows/format-on-demand.yml +305 -0
  12. package/.github/workflows/lint-doc-links.yml +8 -5
  13. package/.github/workflows/markdown-json.yml +6 -2
  14. package/.github/workflows/prettier-autofix.yml +195 -0
  15. package/.github/workflows/update-dotnet-tools.yml +80 -0
  16. package/.github/workflows/yaml-format-lint.yml +41 -0
  17. package/.lychee.toml +4 -4
  18. package/.markdownlint.jsonc +21 -0
  19. package/.pre-commit-config.yaml +11 -3
  20. package/.yamllint.yaml +31 -0
  21. package/AGENTS.md +5 -1
  22. package/CHANGELOG.md +11 -0
  23. package/CONTRIBUTING.md +49 -0
  24. package/CONTRIBUTING.md.meta +7 -0
  25. package/EDITOR_TOOLS_GUIDE.md +4 -0
  26. package/Editor/AnimationEventEditor.cs +337 -160
  27. package/Editor/Core/Helper/AnimationEventHelpers.cs +178 -152
  28. package/Editor/CustomEditors/PersistentDirectoryGUI.cs +20 -11
  29. package/Editor/CustomEditors/TexturePlatformOverrideEntryDrawer.cs +11 -2
  30. package/Editor/FitTextureSizeWindow.cs +43 -19
  31. package/Editor/PersistentDirectorySettings.cs +64 -12
  32. package/Editor/PrefabChecker.cs +72 -5
  33. package/Editor/Sprites/AnimationCopier.cs +132 -56
  34. package/Editor/Sprites/AnimationCreator.cs +63 -22
  35. package/Editor/Sprites/AnimationViewerWindow.cs +42 -6
  36. package/Editor/Sprites/TexturePlatformNameHelper.cs +50 -39
  37. package/Editor/Sprites/TextureResizerWizard.cs +23 -1
  38. package/Editor/Sprites/TextureSettingsApplierWindow.cs +148 -85
  39. package/Editor/Tools/ImageBlurTool.cs +81 -10
  40. package/Editor/Utils/EditorUi.cs +1 -1
  41. package/Editor/Utils/ScriptableObjectSingletonCreator.cs +1 -1
  42. package/GETTING_STARTED.md +40 -56
  43. package/RANDOM_PERFORMANCE.md +12 -12
  44. package/README.md +395 -2407
  45. package/RELATIONAL_COMPONENTS.md +92 -83
  46. package/Runtime/AssemblyInfo.cs +2 -0
  47. package/Runtime/Core/Attributes/NotNullAttribute.cs +1 -3
  48. package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +50 -5
  49. package/Runtime/Core/DataStructure/CyclicBuffer.cs +0 -1
  50. package/Runtime/Core/Extension/RandomExtensions.cs +68 -0
  51. package/Runtime/Core/Extension/WallstopStudiosLogger.cs +16 -0
  52. package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +4 -1
  53. package/Runtime/Core/Helper/ReflectionHelpers.cs +21 -10
  54. package/Runtime/Core/Helper/SpriteHelpers.cs +3 -1
  55. package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +45 -1
  56. package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs +13 -5
  57. package/Runtime/Core/Serialization/JsonConverters/ResolutionConverter.cs +1 -1
  58. package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs +1 -1
  59. package/Runtime/Core/Serialization/Serializer.cs +101 -0
  60. package/Runtime/Integrations/VContainer/AssemblyInfo.cs +9 -0
  61. package/Runtime/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
  62. package/Runtime/Integrations/VContainer/ObjectResolverRelationalExtensions.cs +96 -0
  63. package/Runtime/Integrations/VContainer/RelationalComponentEntryPoint.cs +90 -10
  64. package/Runtime/Integrations/VContainer/RelationalComponentsBuilderExtensions.cs +13 -1
  65. package/Runtime/Integrations/VContainer/RelationalObjectPools.cs +114 -0
  66. package/Runtime/Integrations/VContainer/RelationalObjectPools.cs.meta +11 -0
  67. package/Runtime/Integrations/VContainer/RelationalSceneAssignmentOptions.cs +16 -4
  68. package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs +241 -0
  69. package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs.meta +11 -0
  70. package/Runtime/Integrations/Zenject/AssemblyInfo.cs +9 -0
  71. package/Runtime/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
  72. package/Runtime/Integrations/Zenject/DiContainerRelationalExtensions.cs +69 -2
  73. package/Runtime/Integrations/Zenject/RelationalComponentSceneInitializer.cs +89 -12
  74. package/Runtime/Integrations/Zenject/RelationalComponentsInstaller.cs +23 -1
  75. package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs +44 -0
  76. package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs.meta +11 -0
  77. package/Runtime/Integrations/Zenject/RelationalSceneAssignmentOptions.cs +16 -10
  78. package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs +243 -0
  79. package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs.meta +11 -0
  80. package/Runtime/Tags/AttributeMetadataCache.cs +1 -4
  81. package/Runtime/Utils/Buffers.cs +4 -4
  82. package/Runtime/Utils/ScriptableObjectSingleton.cs +0 -1
  83. package/Runtime/Utils/SetTextureImportData.cs +3 -1
  84. package/Runtime/Utils/TextureScale.cs +10 -2
  85. package/Runtime/Visuals/UGUI/EnhancedImage.cs +6 -0
  86. package/Runtime/Visuals/UIToolkit/LayeredImage.cs +4 -1
  87. package/SERIALIZATION.md +15 -0
  88. package/SPATIAL_TREE_2D_PERFORMANCE.md +85 -82
  89. package/SPATIAL_TREE_3D_PERFORMANCE.md +94 -91
  90. package/Samples~/DI - VContainer/README.md +232 -51
  91. package/Samples~/DI - VContainer/Scripts/GameLifetimeScope.cs +22 -4
  92. package/Samples~/DI - VContainer/Scripts/RelationalConsumer.cs +5 -2
  93. package/Samples~/DI - VContainer/Scripts/Spawner.cs +113 -4
  94. package/Samples~/DI - Zenject/README.md +217 -53
  95. package/Samples~/DI - Zenject/Scripts/RelationalConsumer.cs +3 -0
  96. package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs +37 -0
  97. package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs.meta +12 -0
  98. package/Samples~/DI - Zenject/Scripts/SpawnerZenject.cs +74 -3
  99. package/Samples~/Random - PRNG/README.md +2 -1
  100. package/Samples~/Relational Components - Basic/README.md +3 -1
  101. package/Samples~/Serialization - JSON/README.md +2 -1
  102. package/Samples~/Spatial Structures - 2D and 3D/README.md +2 -1
  103. package/Samples~/UGUI - EnhancedImage/README.md +2 -1
  104. package/Samples~/UI Toolkit - MultiFile Selector (Editor)/README.md +2 -1
  105. package/THIRD_PARTY_NOTICES.md +1 -1
  106. package/Tests/Editor/Attributes/AnimationEventHelpersTests.cs +16 -0
  107. package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +3 -3
  108. package/Tests/Editor/Integrations/VContainer/VContainerRelationalEntryPointTests.cs +6 -2
  109. package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs +170 -0
  110. package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs.meta +11 -0
  111. package/Tests/Editor/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Editor.VContainer.asmdef +2 -1
  112. package/Tests/Editor/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Editor.Zenject.asmdef +3 -2
  113. package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs +131 -0
  114. package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs.meta +11 -0
  115. package/Tests/Editor/Integrations/Zenject/ZenjectRelationalInitializerTests.cs +6 -2
  116. package/Tests/Editor/PersistentDirectorySettingsTests.cs +59 -0
  117. package/Tests/Editor/PersistentDirectorySettingsTests.cs.meta +11 -0
  118. package/Tests/Editor/PrefabCheckerReportTests.cs +32 -0
  119. package/Tests/Editor/PrefabCheckerReportTests.cs.meta +11 -0
  120. package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +64 -0
  121. package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs.meta +11 -0
  122. package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +1 -1
  123. package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +38 -0
  124. package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs.meta +11 -0
  125. package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +1 -1
  126. package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +12 -12
  127. package/Tests/Editor/Sprites/SpriteCropperTests.cs +9 -9
  128. package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +3 -3
  129. package/Tests/Editor/Sprites/TexturePlatformNameHelperTests.cs +18 -0
  130. package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +5 -5
  131. package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +3 -3
  132. package/Tests/Editor/Sprites/TextureSettingsApplierWizardAdditionalTests.cs +4 -4
  133. package/Tests/Editor/Sprites/TextureSettingsApplierWizardTests.cs +4 -4
  134. package/Tests/Editor/Tools/ImageBlurToolTests.cs +22 -110
  135. package/Tests/Editor/Utils/CommonTestBase.cs +43 -1
  136. package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorTests.cs +5 -5
  137. package/Tests/Editor/Windows/FitTextureSizeWindowTests.cs +66 -74
  138. package/Tests/Runtime/Attributes/RelationalComponentInitializerTests.cs +4 -15
  139. package/Tests/Runtime/DataStructures/SpatialTree3DBoundsConsistencyTests.cs +29 -29
  140. package/Tests/Runtime/Integrations/VContainer/RelationalComponentsVContainerTests.cs +259 -218
  141. package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs +86 -0
  142. package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs.meta +11 -0
  143. package/Tests/Runtime/Integrations/Zenject/RelationalComponentsZenjectTests.cs +255 -227
  144. package/Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs +5 -0
  145. package/Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs +3 -0
  146. package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs +30 -0
  147. package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs.meta +11 -0
  148. package/Tests/Runtime/Serialization/JsonConverterTests.cs +8 -12
  149. package/Tests/Runtime/Serialization/JsonSerializationTest.cs +16 -5
  150. package/Tests/Runtime/Serialization/SerializerAdditionalTests.cs +12 -0
  151. package/Tests/Runtime/Serialization/SerializerFileIoTests.cs +105 -0
  152. package/Tests/Runtime/Serialization/SerializerFileIoTests.cs.meta +11 -0
  153. package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs +247 -0
  154. package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs.meta +11 -0
  155. package/Tests/Runtime/TestUtils/CommonTestBase.cs +88 -0
  156. package/Tests/Runtime/Utils/CoroutineHandlerTests.cs +1 -1
  157. package/Tests/Runtime/Utils/LZMAComprehensiveTests.cs +1 -1
  158. package/Tests/Runtime/Utils/LZMATests.cs +1 -1
  159. package/Tests/Runtime/Utils/MatchColliderToSpriteTests.cs +1 -1
  160. package/Tests/Runtime/Visuals/EnhancedImageTests.cs +25 -56
  161. package/Tests/Runtime/Visuals/VisualsTestHelpers.cs +1 -8
  162. package/package-lock.json.meta +7 -0
  163. package/package.json +8 -4
  164. package/scripts/check-eol.ps1 +4 -5
  165. package/scripts/lint-tests.ps1 +156 -0
  166. package/scripts/lint-tests.ps1.meta +7 -0
  167. package/scripts/normalize-eol.ps1 +6 -9
  168. package/.github/workflows/csharpier.yml +0 -135
@@ -185,7 +185,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
185
185
  private static void ModifyClip(string relPath)
186
186
  {
187
187
  AnimationClip clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(relPath);
188
- Assert.IsNotNull(clip);
188
+ Assert.IsTrue(clip != null);
189
189
  clip.frameRate = clip.frameRate + 1f;
190
190
  EditorUtility.SetDirty(clip);
191
191
  }
@@ -0,0 +1,38 @@
1
+ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
2
+ {
3
+ #if UNITY_EDITOR
4
+ using NUnit.Framework;
5
+ using UnityEditor;
6
+ using UnityEngine;
7
+ using WallstopStudios.UnityHelpers.Editor.Sprites;
8
+
9
+ public sealed class AnimationViewerWindowTests
10
+ {
11
+ [Test]
12
+ public void EditorLayerDataBuildsSpriteListFromClip()
13
+ {
14
+ // Build a test clip with 3 sprite keyframes
15
+ AnimationClip clip = new AnimationClip();
16
+ Texture2D tex = new Texture2D(2, 2);
17
+ Sprite s1 = Sprite.Create(tex, new Rect(0, 0, 1, 1), Vector2.zero);
18
+ Sprite s2 = Sprite.Create(tex, new Rect(0, 0, 1, 1), Vector2.zero);
19
+ Sprite s3 = Sprite.Create(tex, new Rect(0, 0, 1, 1), Vector2.zero);
20
+
21
+ EditorCurveBinding binding = EditorCurveBinding.PPtrCurve(
22
+ string.Empty,
23
+ typeof(SpriteRenderer),
24
+ "m_Sprite"
25
+ );
26
+ ObjectReferenceKeyframe[] keys = new ObjectReferenceKeyframe[3];
27
+ keys[0] = new ObjectReferenceKeyframe { time = 0f, value = s1 };
28
+ keys[1] = new ObjectReferenceKeyframe { time = 0.1f, value = s2 };
29
+ keys[2] = new ObjectReferenceKeyframe { time = 0.2f, value = s3 };
30
+ AnimationUtility.SetObjectReferenceCurve(clip, binding, keys);
31
+
32
+ var instance = new AnimationViewerWindow.EditorLayerData(clip);
33
+ Assert.NotNull(instance);
34
+ Assert.AreEqual(3, instance.Sprites.Count);
35
+ }
36
+ }
37
+ #endif
38
+ }
@@ -0,0 +1,11 @@
1
+ fileFormatVersion: 2
2
+ guid: 85db80503d91fb64c903adb74cee007a
3
+ MonoImporter:
4
+ externalObjects: {}
5
+ serializedVersion: 2
6
+ defaultReferences: []
7
+ executionOrder: 0
8
+ icon: {instanceID: 0}
9
+ userData:
10
+ assetBundleName:
11
+ assetBundleVariant:
@@ -57,7 +57,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
57
57
 
58
58
  string atlasPath = Path.Combine(Root, "TestAtlas.spriteatlas").Replace('\\', '/');
59
59
  SpriteAtlas atlas = AssetDatabase.LoadAssetAtPath<SpriteAtlas>(atlasPath);
60
- Assert.IsNotNull(atlas, ".spriteatlas should be generated");
60
+ Assert.IsTrue(atlas != null, ".spriteatlas should be generated");
61
61
  }
62
62
 
63
63
  private static void EnsureFolder(string relPath)
@@ -36,7 +36,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
36
36
  AssetDatabase.Refresh();
37
37
 
38
38
  TextureImporter imp = AssetImporter.GetAtPath(src) as TextureImporter;
39
- Assert.IsNotNull(imp);
39
+ Assert.IsTrue(imp != null);
40
40
  imp.textureType = TextureImporterType.Sprite;
41
41
  imp.spriteImportMode = SpriteImportMode.Single;
42
42
  imp.isReadable = true;
@@ -61,13 +61,13 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
61
61
 
62
62
  string dst = (Root + "/Cropped_pad_src.png").Replace('\\', '/');
63
63
  Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(dst);
64
- Assert.IsNotNull(tex);
64
+ Assert.IsTrue(tex != null);
65
65
  // Expected size: (10 + 2 + 1) x (10 + 3 + 0) = 13x13
66
66
  Assert.That(tex.width, Is.EqualTo(13));
67
67
  Assert.That(tex.height, Is.EqualTo(13));
68
68
 
69
69
  TextureImporter newImp = AssetImporter.GetAtPath(dst) as TextureImporter;
70
- Assert.IsNotNull(newImp);
70
+ Assert.IsTrue(newImp != null);
71
71
  Vector2 pivot = newImp.spritePivot;
72
72
  // Expected pivot in pixels = (10-3, 10-2) = (7,8) → normalized (7/13, 8/13)
73
73
  Assert.That(pivot.x, Is.InRange(7f / 13f - 1e-3f, 7f / 13f + 1e-3f));
@@ -83,7 +83,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
83
83
  AssetDatabase.Refresh();
84
84
 
85
85
  TextureImporter imp = AssetImporter.GetAtPath(src) as TextureImporter;
86
- Assert.IsNotNull(imp);
86
+ Assert.IsTrue(imp != null);
87
87
  imp.textureType = TextureImporterType.Sprite;
88
88
  imp.spriteImportMode = SpriteImportMode.Single;
89
89
  imp.isReadable = true;
@@ -117,7 +117,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
117
117
  AssetDatabase.Refresh();
118
118
 
119
119
  TextureImporter imp = AssetImporter.GetAtPath(src) as TextureImporter;
120
- Assert.IsNotNull(imp);
120
+ Assert.IsTrue(imp != null);
121
121
  imp.textureType = TextureImporterType.Sprite;
122
122
  imp.spriteImportMode = SpriteImportMode.Single;
123
123
  imp.isReadable = false; // start unreadable
@@ -137,12 +137,12 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
137
137
 
138
138
  // Original should be restored to unreadable
139
139
  imp = AssetImporter.GetAtPath(src) as TextureImporter;
140
- Assert.IsNotNull(imp);
140
+ Assert.IsTrue(imp != null);
141
141
  Assert.That(imp.isReadable, Is.False);
142
142
 
143
143
  string dst = (Root + "/Cropped_readable_toggle.png").Replace('\\', '/');
144
144
  TextureImporter newImp = AssetImporter.GetAtPath(dst) as TextureImporter;
145
- Assert.IsNotNull(newImp);
145
+ Assert.IsTrue(newImp != null);
146
146
  Assert.That(
147
147
  newImp.isReadable,
148
148
  Is.False,
@@ -165,7 +165,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
165
165
 
166
166
  string dst2 = (Root + "/Cropped_readable_toggle.png").Replace('\\', '/');
167
167
  newImp = AssetImporter.GetAtPath(dst2) as TextureImporter;
168
- Assert.IsNotNull(newImp);
168
+ Assert.IsTrue(newImp != null);
169
169
  Assert.That(newImp.isReadable, Is.True);
170
170
  }
171
171
 
@@ -194,12 +194,12 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
194
194
  AssetDatabase.Refresh();
195
195
  string dst = (Root + "/Cropped_all_transparent.png").Replace('\\', '/');
196
196
  Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(dst);
197
- Assert.IsNotNull(tex);
197
+ Assert.IsTrue(tex != null);
198
198
  Assert.That(tex.width, Is.EqualTo(1));
199
199
  Assert.That(tex.height, Is.EqualTo(1));
200
200
 
201
201
  TextureImporter newImp = AssetImporter.GetAtPath(dst) as TextureImporter;
202
- Assert.IsNotNull(newImp);
202
+ Assert.IsTrue(newImp != null);
203
203
  Vector2 pivot = newImp.spritePivot;
204
204
  Assert.That(pivot.x, Is.InRange(0.49f, 0.51f));
205
205
  Assert.That(pivot.y, Is.InRange(0.49f, 0.51f));
@@ -213,7 +213,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
213
213
  AssetDatabase.Refresh();
214
214
 
215
215
  TextureImporter imp = AssetImporter.GetAtPath(src) as TextureImporter;
216
- Assert.IsNotNull(imp);
216
+ Assert.IsTrue(imp != null);
217
217
  imp.textureType = TextureImporterType.Sprite;
218
218
  imp.spriteImportMode = SpriteImportMode.Multiple;
219
219
  imp.SaveAndReimport();
@@ -232,7 +232,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
232
232
  string dst = (Root + "/Cropped_multi.png").Replace('\\', '/');
233
233
  Assert.That(File.Exists(RelToFull(dst)), Is.False);
234
234
  Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(src);
235
- Assert.IsNotNull(tex);
235
+ Assert.IsTrue(tex != null);
236
236
  Assert.That(tex.width, Is.EqualTo(16));
237
237
  Assert.That(tex.height, Is.EqualTo(16));
238
238
  }
@@ -36,7 +36,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
36
36
 
37
37
  // Ensure sprite importer single + readable
38
38
  TextureImporter imp = AssetImporter.GetAtPath(src) as TextureImporter;
39
- Assert.IsNotNull(imp);
39
+ Assert.IsTrue(imp != null);
40
40
  imp.textureType = TextureImporterType.Sprite;
41
41
  imp.spriteImportMode = SpriteImportMode.Single;
42
42
  imp.spritePivot = new Vector2(0.5f, 0.5f); // center
@@ -45,9 +45,9 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
45
45
 
46
46
  SpriteCropper window = Track(ScriptableObject.CreateInstance<SpriteCropper>());
47
47
  window._overwriteOriginals = true;
48
- window._inputDirectories = new System.Collections.Generic.List<UnityEngine.Object>
48
+ window._inputDirectories = new System.Collections.Generic.List<Object>
49
49
  {
50
- AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(Root),
50
+ AssetDatabase.LoadAssetAtPath<Object>(Root),
51
51
  };
52
52
  window.FindFilesToProcess();
53
53
  window.ProcessFoundSprites();
@@ -56,13 +56,13 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
56
56
 
57
57
  // Source should be overwritten and cropped to 10x10
58
58
  Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(src);
59
- Assert.IsNotNull(tex);
59
+ Assert.IsTrue(tex != null);
60
60
  Assert.That(tex.width, Is.EqualTo(10));
61
61
  Assert.That(tex.height, Is.EqualTo(10));
62
62
 
63
63
  // Pivot should remain effectively center after crop
64
64
  imp = AssetImporter.GetAtPath(src) as TextureImporter;
65
- Assert.IsNotNull(imp);
65
+ Assert.IsTrue(imp != null);
66
66
  Assert.That(imp.spriteImportMode, Is.EqualTo(SpriteImportMode.Single));
67
67
  Vector2 pivot = imp.spritePivot;
68
68
  Assert.That(pivot.x, Is.InRange(0.49f, 0.51f));
@@ -86,10 +86,10 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
86
86
 
87
87
  SpriteCropper window = Track(ScriptableObject.CreateInstance<SpriteCropper>());
88
88
  window._overwriteOriginals = false;
89
- window._outputDirectory = AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(outDir);
90
- window._inputDirectories = new System.Collections.Generic.List<UnityEngine.Object>
89
+ window._outputDirectory = AssetDatabase.LoadAssetAtPath<Object>(outDir);
90
+ window._inputDirectories = new System.Collections.Generic.List<Object>
91
91
  {
92
- AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(Root),
92
+ AssetDatabase.LoadAssetAtPath<Object>(Root),
93
93
  };
94
94
  window.FindFilesToProcess();
95
95
  window.ProcessFoundSprites();
@@ -100,7 +100,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
100
100
  Assert.That(File.Exists(RelToFull(dst)), Is.True, "Cropped output should exist");
101
101
 
102
102
  Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(dst);
103
- Assert.IsNotNull(tex);
103
+ Assert.IsTrue(tex != null);
104
104
  Assert.That(tex.width, Is.EqualTo(4));
105
105
  Assert.That(tex.height, Is.EqualTo(4));
106
106
  }
@@ -35,7 +35,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
35
35
  AssetDatabase.Refresh();
36
36
 
37
37
  TextureImporter imp = AssetImporter.GetAtPath(path) as TextureImporter;
38
- Assert.IsNotNull(imp);
38
+ Assert.IsTrue(imp != null);
39
39
  imp.textureType = TextureImporterType.Sprite;
40
40
  imp.spriteImportMode = SpriteImportMode.Single;
41
41
  imp.isReadable = true;
@@ -45,9 +45,9 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
45
45
  SpritePivotAdjuster window = Track(
46
46
  ScriptableObject.CreateInstance<SpritePivotAdjuster>()
47
47
  );
48
- window._directoryPaths = new System.Collections.Generic.List<UnityEngine.Object>
48
+ window._directoryPaths = new System.Collections.Generic.List<Object>
49
49
  {
50
- AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(Root),
50
+ AssetDatabase.LoadAssetAtPath<Object>(Root),
51
51
  };
52
52
  window._alphaCutoff = 0.01f;
53
53
  window._skipUnchanged = false;
@@ -23,6 +23,24 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
23
23
  bool hasIOS = System.Array.IndexOf(names, "iOS") >= 0;
24
24
  Assert.IsTrue(hasIPhone || hasIOS);
25
25
  }
26
+
27
+ [Test]
28
+ public void CachesResultsAndIsSorted()
29
+ {
30
+ string[] a = TexturePlatformNameHelper.GetKnownPlatformNames();
31
+ string[] b = TexturePlatformNameHelper.GetKnownPlatformNames();
32
+ // Expect the exact same reference due to caching
33
+ Assert.AreSame(a, b);
34
+
35
+ // Verify ascending ordinal order
36
+ for (int i = 1; i < a.Length; i++)
37
+ {
38
+ Assert.LessOrEqual(
39
+ string.Compare(a[i - 1], a[i], System.StringComparison.Ordinal),
40
+ 0
41
+ );
42
+ }
43
+ }
26
44
  }
27
45
  #endif
28
46
  }
@@ -51,7 +51,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
51
51
 
52
52
  AssetDatabase.Refresh();
53
53
  Texture2D tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
54
- Assert.IsNotNull(tex, "Texture should exist after resize");
54
+ Assert.IsTrue(tex != null, "Texture should exist after resize");
55
55
  Assert.That(tex.width, Is.EqualTo(32), "Width should double");
56
56
  Assert.That(tex.height, Is.EqualTo(20), "Height should double");
57
57
  }
@@ -125,7 +125,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
125
125
  wizard.heightMultiplier = 1f;
126
126
  wizard.scalingResizeAlgorithm = TextureResizerWizard.ResizeAlgorithm.Point;
127
127
  DefaultAsset outAsset = AssetDatabase.LoadAssetAtPath<DefaultAsset>(OutRoot);
128
- Assert.IsNotNull(outAsset, "Output folder asset missing");
128
+ Assert.IsTrue(outAsset != null, "Output folder asset missing");
129
129
  wizard.outputFolder = outAsset;
130
130
  wizard.OnWizardCreate();
131
131
 
@@ -136,7 +136,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
136
136
 
137
137
  string outPath = Path.Combine(OutRoot, "out.png").Replace('\\', '/');
138
138
  Texture2D outTex = AssetDatabase.LoadAssetAtPath<Texture2D>(outPath);
139
- Assert.IsNotNull(outTex, "Expected resized texture in output folder");
139
+ Assert.IsTrue(outTex != null, "Expected resized texture in output folder");
140
140
  Assert.That(outTex.width, Is.EqualTo(16));
141
141
  Assert.That(outTex.height, Is.EqualTo(8));
142
142
  }
@@ -176,7 +176,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
176
176
  AssetDatabase.Refresh();
177
177
 
178
178
  TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
179
- Assert.IsNotNull(importer);
179
+ Assert.IsTrue(importer != null);
180
180
  importer.isReadable = false;
181
181
  importer.SaveAndReimport();
182
182
 
@@ -196,7 +196,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
196
196
 
197
197
  AssetDatabase.Refresh();
198
198
  importer = AssetImporter.GetAtPath(path) as TextureImporter;
199
- Assert.IsNotNull(importer);
199
+ Assert.IsTrue(importer != null);
200
200
  Assert.IsFalse(importer.isReadable, "Importer readability should be restored");
201
201
  }
202
202
 
@@ -55,7 +55,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
55
55
  out TextureImporter importer
56
56
  );
57
57
  Assert.IsTrue(changed, "Expected API to apply changes");
58
- Assert.IsNotNull(importer);
58
+ Assert.IsTrue(importer != null);
59
59
  importer.SaveAndReimport();
60
60
 
61
61
  TextureImporterPlatformSettings ps = importer.GetDefaultPlatformTextureSettings();
@@ -88,7 +88,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
88
88
  out TextureImporter importer
89
89
  );
90
90
  Assert.IsTrue(changed, "Expected override to apply");
91
- Assert.IsNotNull(importer);
91
+ Assert.IsTrue(importer != null);
92
92
  importer.SaveAndReimport();
93
93
 
94
94
  TextureImporterPlatformSettings ops = importer.GetPlatformTextureSettings("Standalone");
@@ -120,7 +120,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
120
120
  out TextureImporter importer
121
121
  );
122
122
  Assert.IsTrue(changed, "Expected override to apply even for unknown platform name");
123
- Assert.IsNotNull(importer);
123
+ Assert.IsTrue(importer != null);
124
124
  importer.SaveAndReimport();
125
125
 
126
126
  TextureImporterPlatformSettings ops = importer.GetPlatformTextureSettings(
@@ -75,8 +75,8 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
75
75
 
76
76
  impIncluded = AssetImporter.GetAtPath(included) as TextureImporter;
77
77
  impOther = AssetImporter.GetAtPath(other) as TextureImporter;
78
- Assert.IsNotNull(impIncluded);
79
- Assert.IsNotNull(impOther);
78
+ Assert.IsTrue(impIncluded != null);
79
+ Assert.IsTrue(impOther != null);
80
80
 
81
81
  Assert.That(impIncluded.isReadable, Is.False);
82
82
  Assert.That(impIncluded.wrapMode, Is.EqualTo(TextureWrapMode.Clamp));
@@ -187,7 +187,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
187
187
  AssetDatabase.Refresh();
188
188
 
189
189
  TextureImporter imp = AssetImporter.GetAtPath(path) as TextureImporter;
190
- Assert.IsNotNull(imp);
190
+ Assert.IsTrue(imp != null);
191
191
  TextureImporterPlatformSettings ops = imp.GetPlatformTextureSettings("Standalone");
192
192
  Assert.IsTrue(ops.overridden);
193
193
  Assert.AreEqual(256, ops.maxTextureSize);
@@ -203,7 +203,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
203
203
 
204
204
  // Set importer to desired state first
205
205
  TextureImporter imp = AssetImporter.GetAtPath(path) as TextureImporter;
206
- Assert.IsNotNull(imp);
206
+ Assert.IsTrue(imp != null);
207
207
  imp.wrapMode = TextureWrapMode.Clamp;
208
208
  imp.filterMode = FilterMode.Bilinear;
209
209
  TextureImporterPlatformSettings ps = imp.GetDefaultPlatformTextureSettings();
@@ -48,9 +48,9 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
48
48
  };
49
49
 
50
50
  // Set directories list
51
- window.directories = new System.Collections.Generic.List<UnityEngine.Object>
51
+ window.directories = new System.Collections.Generic.List<Object>
52
52
  {
53
- AssetDatabase.LoadAssetAtPath<UnityEngine.Object>(Root),
53
+ AssetDatabase.LoadAssetAtPath<Object>(Root),
54
54
  };
55
55
 
56
56
  // Configure changes
@@ -69,8 +69,8 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Sprites
69
69
  AssetDatabase.Refresh();
70
70
  TextureImporter impA = AssetImporter.GetAtPath(a) as TextureImporter;
71
71
  TextureImporter impB = AssetImporter.GetAtPath(b) as TextureImporter;
72
- Assert.IsNotNull(impA);
73
- Assert.IsNotNull(impB);
72
+ Assert.IsTrue(impA != null);
73
+ Assert.IsTrue(impB != null);
74
74
 
75
75
  // Verify a subset of settings applied
76
76
  Assert.That(impA.isReadable, Is.False); // isReadOnly=true → not readable
@@ -1,134 +1,46 @@
1
1
  namespace WallstopStudios.UnityHelpers.Tests.Editor.Tools
2
2
  {
3
3
  #if UNITY_EDITOR
4
- using System.Collections.Generic;
5
- using System.IO;
6
- using System.Linq;
7
4
  using NUnit.Framework;
8
- using UnityEditor;
9
5
  using UnityEngine;
10
- using Object = UnityEngine.Object;
6
+ using WallstopStudios.UnityHelpers.Editor.Tools;
11
7
 
12
8
  public sealed class ImageBlurToolTests
13
9
  {
14
- private const string TempRoot = "Assets/Temp/ImageBlurToolTests";
15
-
16
- [SetUp]
17
- public void SetUp()
18
- {
19
- EnsureFolder(TempRoot);
20
- }
21
-
22
- [TearDown]
23
- public void TearDown()
24
- {
25
- AssetDatabase.DeleteAsset("Assets/Temp");
26
- AssetDatabase.Refresh();
27
- }
28
-
29
10
  [Test]
30
- public void GenerateGaussianKernelIsNormalizedAndSymmetric()
11
+ public void KernelHasExpectedLengthAndNormalizes()
31
12
  {
32
- float[] k = WallstopStudios.UnityHelpers.Editor.Tools.ImageBlurTool.KernelForTests(5);
33
- Assert.IsNotNull(k, "Kernel should not be null");
34
- Assert.That(k.Length, Is.EqualTo(11), "Kernel size should be 2r+1");
35
-
36
- float sum = k.Sum();
37
- Assert.That(Mathf.Abs(1f - sum) < 1e-3f, "Kernel should sum to 1");
38
-
39
- for (int i = 0; i < k.Length; i++)
13
+ for (int radius = 1; radius <= 4; radius++)
40
14
  {
41
- Assert.That(
42
- Mathf.Abs(k[i] - k[k.Length - 1 - i]) < 1e-6f,
43
- $"Kernel must be symmetric at {i}"
44
- );
15
+ float[] kernel = ImageBlurTool.KernelForTests(radius);
16
+ Assert.NotNull(kernel);
17
+ Assert.AreEqual(radius * 2 + 1, kernel.Length);
18
+ float sum = 0f;
19
+ for (int i = 0; i < kernel.Length; i++)
20
+ {
21
+ sum += kernel[i];
22
+ }
23
+ Assert.That(sum, Is.InRange(0.999f, 1.001f));
45
24
  }
46
25
  }
47
26
 
48
27
  [Test]
49
- public void CreateBlurredTextureSoftensHighContrastPixel()
28
+ public void BlurredTextureMatchesInputDimensions()
50
29
  {
51
- Texture2D src = new(5, 5, TextureFormat.RGBA32, false);
52
- Color[] pixels = Enumerable.Repeat(Color.black, 25).ToArray();
53
- pixels[12] = Color.white;
54
- src.SetPixels(pixels);
55
- src.Apply();
56
-
57
- Texture2D blurred =
58
- WallstopStudios.UnityHelpers.Editor.Tools.ImageBlurTool.BlurredForTests(src, 2);
59
- Assert.IsNotNull(blurred, "Blurred texture should be created");
60
- Assert.That(blurred.width, Is.EqualTo(5));
61
- Assert.That(blurred.height, Is.EqualTo(5));
62
-
63
- Color[] outPix = blurred.GetPixels();
64
- Assert.That(outPix[12].maxColorComponent < 1f, "Center intensity should reduce");
65
- Assert.That(outPix[11].maxColorComponent > 0f, "Neighbor should gain intensity");
66
- Assert.That(outPix[13].maxColorComponent > 0f, "Neighbor should gain intensity");
67
- }
68
-
69
- [Test]
70
- public void TrySyncDirectoryCollectsTextureAssets()
71
- {
72
- string texPath = Path.Combine(TempRoot, "tex.png").Replace('\\', '/');
73
- CreatePng(texPath, 8, 8, Color.red);
74
-
75
- AssetDatabase.Refresh();
76
- Object folderObj = AssetDatabase.LoadAssetAtPath<Object>(TempRoot);
77
- Assert.IsNotNull(folderObj, "Temp folder not found as asset");
78
-
79
- List<Texture2D> list = new();
80
- WallstopStudios.UnityHelpers.Editor.Tools.ImageBlurTool.TrySyncDirectory(
81
- TempRoot,
82
- list
83
- );
84
- Assert.That(
85
- list.Count,
86
- Is.GreaterThanOrEqualTo(1),
87
- "Expected at least one texture collected"
88
- );
89
- Assert.IsTrue(
90
- list.Any(t => t != null && t.name == "tex"),
91
- "Texture tex should be present"
92
- );
93
- }
94
-
95
- private static void EnsureFolder(string relPath)
96
- {
97
- string[] parts = relPath.Split('/');
98
- string cur = parts[0];
99
- for (int i = 1; i < parts.Length; i++)
30
+ Texture2D tex = new Texture2D(8, 8, TextureFormat.RGBA32, false);
31
+ for (int y = 0; y < tex.height; y++)
100
32
  {
101
- string next = cur + "/" + parts[i];
102
- if (!AssetDatabase.IsValidFolder(next))
33
+ for (int x = 0; x < tex.width; x++)
103
34
  {
104
- AssetDatabase.CreateFolder(cur, parts[i]);
35
+ tex.SetPixel(x, y, Color.white);
105
36
  }
106
- cur = next;
107
37
  }
108
- }
109
-
110
- private static void CreatePng(string relPath, int w, int h, Color c)
111
- {
112
- string dir = Path.GetDirectoryName(relPath).Replace('\\', '/');
113
- EnsureFolder(dir);
114
- Texture2D t = new(w, h, TextureFormat.RGBA32, false);
115
- Color[] pix = Enumerable.Repeat(c, w * h).ToArray();
116
- t.SetPixels(pix);
117
- t.Apply();
118
- byte[] data = t.EncodeToPNG();
119
- File.WriteAllBytes(RelToFull(relPath), data);
120
- }
38
+ tex.Apply();
121
39
 
122
- private static string RelToFull(string rel)
123
- {
124
- return Path.Combine(
125
- Application.dataPath.Substring(
126
- 0,
127
- Application.dataPath.Length - "Assets".Length
128
- ),
129
- rel
130
- )
131
- .Replace('\\', '/');
40
+ Texture2D blurred = ImageBlurTool.BlurredForTests(tex, 2);
41
+ Assert.IsTrue(blurred != null);
42
+ Assert.AreEqual(tex.width, blurred.width);
43
+ Assert.AreEqual(tex.height, blurred.height);
132
44
  }
133
45
  }
134
46
  #endif
@@ -40,7 +40,6 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Utils
40
40
  #if UNITY_EDITOR
41
41
  if (!Application.isPlaying)
42
42
  {
43
- // In EditMode tests, use EditorSceneManager as CreateScene is play-mode only
44
43
  scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
45
44
  }
46
45
  else
@@ -55,6 +54,7 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Utils
55
54
  {
56
55
  SceneManager.SetActiveScene(scene);
57
56
  }
57
+
58
58
  _trackedScenes.Add(scene);
59
59
  return scene;
60
60
  }
@@ -102,6 +102,27 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Utils
102
102
  {
103
103
  try
104
104
  {
105
+ if (SceneManager.GetActiveScene() == scene)
106
+ {
107
+ int count = SceneManager.sceneCount;
108
+ for (int j = 0; j < count; j++)
109
+ {
110
+ Scene candidate = SceneManager.GetSceneAt(j);
111
+ if (
112
+ candidate.IsValid()
113
+ && candidate.isLoaded
114
+ && candidate != scene
115
+ )
116
+ {
117
+ SceneManager.SetActiveScene(candidate);
118
+ break;
119
+ }
120
+ }
121
+ if (SceneManager.sceneCount == 1)
122
+ {
123
+ continue;
124
+ }
125
+ }
105
126
  EditorSceneManager.CloseScene(scene, true);
106
127
  }
107
128
  catch { }
@@ -170,6 +191,27 @@ namespace WallstopStudios.UnityHelpers.Tests.Editor.Utils
170
191
  {
171
192
  try
172
193
  {
194
+ if (SceneManager.GetActiveScene() == scene)
195
+ {
196
+ int count = SceneManager.sceneCount;
197
+ for (int j = 0; j < count; j++)
198
+ {
199
+ Scene candidate = SceneManager.GetSceneAt(j);
200
+ if (
201
+ candidate.IsValid()
202
+ && candidate.isLoaded
203
+ && candidate != scene
204
+ )
205
+ {
206
+ SceneManager.SetActiveScene(candidate);
207
+ break;
208
+ }
209
+ }
210
+ if (SceneManager.sceneCount == 1)
211
+ {
212
+ continue;
213
+ }
214
+ }
173
215
  EditorSceneManager.CloseScene(scene, true);
174
216
  }
175
217
  catch { }