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.
- package/.editorconfig +1 -1
- package/.gitattributes +1 -1
- package/.githooks/pre-commit +31 -5
- package/.githooks/pre-push +50 -0
- package/.github/dependabot.yml +24 -2
- package/.github/scripts/check-markdown-links.ps1 +77 -0
- package/.github/scripts/check_markdown_links.py +89 -0
- package/.github/scripts/check_markdown_url_encoding.py +74 -0
- package/.github/scripts/validate_markdown_links.py +194 -0
- package/.github/workflows/csharpier-autofix.yml +152 -0
- package/.github/workflows/format-on-demand.yml +305 -0
- package/.github/workflows/lint-doc-links.yml +8 -5
- package/.github/workflows/markdown-json.yml +6 -2
- package/.github/workflows/prettier-autofix.yml +195 -0
- package/.github/workflows/update-dotnet-tools.yml +80 -0
- package/.github/workflows/yaml-format-lint.yml +41 -0
- package/.lychee.toml +4 -4
- package/.markdownlint.jsonc +21 -0
- package/.pre-commit-config.yaml +11 -3
- package/.yamllint.yaml +31 -0
- package/AGENTS.md +5 -1
- package/CHANGELOG.md +11 -0
- package/CONTRIBUTING.md +49 -0
- package/CONTRIBUTING.md.meta +7 -0
- package/EDITOR_TOOLS_GUIDE.md +4 -0
- package/Editor/AnimationEventEditor.cs +337 -160
- package/Editor/Core/Helper/AnimationEventHelpers.cs +178 -152
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs +20 -11
- package/Editor/CustomEditors/TexturePlatformOverrideEntryDrawer.cs +11 -2
- package/Editor/FitTextureSizeWindow.cs +43 -19
- package/Editor/PersistentDirectorySettings.cs +64 -12
- package/Editor/PrefabChecker.cs +72 -5
- package/Editor/Sprites/AnimationCopier.cs +132 -56
- package/Editor/Sprites/AnimationCreator.cs +63 -22
- package/Editor/Sprites/AnimationViewerWindow.cs +42 -6
- package/Editor/Sprites/TexturePlatformNameHelper.cs +50 -39
- package/Editor/Sprites/TextureResizerWizard.cs +23 -1
- package/Editor/Sprites/TextureSettingsApplierWindow.cs +148 -85
- package/Editor/Tools/ImageBlurTool.cs +81 -10
- package/Editor/Utils/EditorUi.cs +1 -1
- package/Editor/Utils/ScriptableObjectSingletonCreator.cs +1 -1
- package/GETTING_STARTED.md +40 -56
- package/RANDOM_PERFORMANCE.md +12 -12
- package/README.md +395 -2407
- package/RELATIONAL_COMPONENTS.md +92 -83
- package/Runtime/AssemblyInfo.cs +2 -0
- package/Runtime/Core/Attributes/NotNullAttribute.cs +1 -3
- package/Runtime/Core/Attributes/RelationalComponentAssigner.cs +50 -5
- package/Runtime/Core/DataStructure/CyclicBuffer.cs +0 -1
- package/Runtime/Core/Extension/RandomExtensions.cs +68 -0
- package/Runtime/Core/Extension/WallstopStudiosLogger.cs +16 -0
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +4 -1
- package/Runtime/Core/Helper/ReflectionHelpers.cs +21 -10
- package/Runtime/Core/Helper/SpriteHelpers.cs +3 -1
- package/Runtime/Core/Helper/UnityMainThreadDispatcher.cs +45 -1
- package/Runtime/Core/Serialization/JsonConverters/GameObjectConverter.cs +13 -5
- package/Runtime/Core/Serialization/JsonConverters/ResolutionConverter.cs +1 -1
- package/Runtime/Core/Serialization/JsonConverters/TypeConverter.cs +1 -1
- package/Runtime/Core/Serialization/Serializer.cs +101 -0
- package/Runtime/Integrations/VContainer/AssemblyInfo.cs +9 -0
- package/Runtime/Integrations/VContainer/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Integrations/VContainer/ObjectResolverRelationalExtensions.cs +96 -0
- package/Runtime/Integrations/VContainer/RelationalComponentEntryPoint.cs +90 -10
- package/Runtime/Integrations/VContainer/RelationalComponentsBuilderExtensions.cs +13 -1
- package/Runtime/Integrations/VContainer/RelationalObjectPools.cs +114 -0
- package/Runtime/Integrations/VContainer/RelationalObjectPools.cs.meta +11 -0
- package/Runtime/Integrations/VContainer/RelationalSceneAssignmentOptions.cs +16 -4
- package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs +241 -0
- package/Runtime/Integrations/VContainer/RelationalSceneLoadListener.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/AssemblyInfo.cs +9 -0
- package/Runtime/Integrations/Zenject/AssemblyInfo.cs.meta +3 -0
- package/Runtime/Integrations/Zenject/DiContainerRelationalExtensions.cs +69 -2
- package/Runtime/Integrations/Zenject/RelationalComponentSceneInitializer.cs +89 -12
- package/Runtime/Integrations/Zenject/RelationalComponentsInstaller.cs +23 -1
- package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs +44 -0
- package/Runtime/Integrations/Zenject/RelationalMemoryPools.cs.meta +11 -0
- package/Runtime/Integrations/Zenject/RelationalSceneAssignmentOptions.cs +16 -10
- package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs +243 -0
- package/Runtime/Integrations/Zenject/RelationalSceneLoadListener.cs.meta +11 -0
- package/Runtime/Tags/AttributeMetadataCache.cs +1 -4
- package/Runtime/Utils/Buffers.cs +4 -4
- package/Runtime/Utils/ScriptableObjectSingleton.cs +0 -1
- package/Runtime/Utils/SetTextureImportData.cs +3 -1
- package/Runtime/Utils/TextureScale.cs +10 -2
- package/Runtime/Visuals/UGUI/EnhancedImage.cs +6 -0
- package/Runtime/Visuals/UIToolkit/LayeredImage.cs +4 -1
- package/SERIALIZATION.md +15 -0
- package/SPATIAL_TREE_2D_PERFORMANCE.md +85 -82
- package/SPATIAL_TREE_3D_PERFORMANCE.md +94 -91
- package/Samples~/DI - VContainer/README.md +232 -51
- package/Samples~/DI - VContainer/Scripts/GameLifetimeScope.cs +22 -4
- package/Samples~/DI - VContainer/Scripts/RelationalConsumer.cs +5 -2
- package/Samples~/DI - VContainer/Scripts/Spawner.cs +113 -4
- package/Samples~/DI - Zenject/README.md +217 -53
- package/Samples~/DI - Zenject/Scripts/RelationalConsumer.cs +3 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs +37 -0
- package/Samples~/DI - Zenject/Scripts/RelationalConsumerPool.cs.meta +12 -0
- package/Samples~/DI - Zenject/Scripts/SpawnerZenject.cs +74 -3
- package/Samples~/Random - PRNG/README.md +2 -1
- package/Samples~/Relational Components - Basic/README.md +3 -1
- package/Samples~/Serialization - JSON/README.md +2 -1
- package/Samples~/Spatial Structures - 2D and 3D/README.md +2 -1
- package/Samples~/UGUI - EnhancedImage/README.md +2 -1
- package/Samples~/UI Toolkit - MultiFile Selector (Editor)/README.md +2 -1
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/Tests/Editor/Attributes/AnimationEventHelpersTests.cs +16 -0
- package/Tests/Editor/Core/Attributes/RelationalComponentAssignerTests.cs +3 -3
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalEntryPointTests.cs +6 -2
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs +170 -0
- package/Tests/Editor/Integrations/VContainer/VContainerRelationalHelpersTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/VContainer/WallstopStudios.UnityHelpers.Tests.Editor.VContainer.asmdef +2 -1
- package/Tests/Editor/Integrations/Zenject/WallstopStudios.UnityHelpers.Tests.Editor.Zenject.asmdef +3 -2
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs +131 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalHelpersTests.cs.meta +11 -0
- package/Tests/Editor/Integrations/Zenject/ZenjectRelationalInitializerTests.cs +6 -2
- package/Tests/Editor/PersistentDirectorySettingsTests.cs +59 -0
- package/Tests/Editor/PersistentDirectorySettingsTests.cs.meta +11 -0
- package/Tests/Editor/PrefabCheckerReportTests.cs +32 -0
- package/Tests/Editor/PrefabCheckerReportTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs +64 -0
- package/Tests/Editor/Sprites/AnimationCopierFilterTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/AnimationCopierWindowTests.cs +1 -1
- package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs +38 -0
- package/Tests/Editor/Sprites/AnimationViewerWindowTests.cs.meta +11 -0
- package/Tests/Editor/Sprites/ScriptableSpriteAtlasEditorTests.cs +1 -1
- package/Tests/Editor/Sprites/SpriteCropperAdditionalTests.cs +12 -12
- package/Tests/Editor/Sprites/SpriteCropperTests.cs +9 -9
- package/Tests/Editor/Sprites/SpritePivotAdjusterTests.cs +3 -3
- package/Tests/Editor/Sprites/TexturePlatformNameHelperTests.cs +18 -0
- package/Tests/Editor/Sprites/TextureResizerWizardTests.cs +5 -5
- package/Tests/Editor/Sprites/TextureSettingsApplierAPITests.cs +3 -3
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardAdditionalTests.cs +4 -4
- package/Tests/Editor/Sprites/TextureSettingsApplierWizardTests.cs +4 -4
- package/Tests/Editor/Tools/ImageBlurToolTests.cs +22 -110
- package/Tests/Editor/Utils/CommonTestBase.cs +43 -1
- package/Tests/Editor/Utils/ScriptableObjectSingletonCreatorTests.cs +5 -5
- package/Tests/Editor/Windows/FitTextureSizeWindowTests.cs +66 -74
- package/Tests/Runtime/Attributes/RelationalComponentInitializerTests.cs +4 -15
- package/Tests/Runtime/DataStructures/SpatialTree3DBoundsConsistencyTests.cs +29 -29
- package/Tests/Runtime/Integrations/VContainer/RelationalComponentsVContainerTests.cs +259 -218
- package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs +86 -0
- package/Tests/Runtime/Integrations/VContainer/RelationalObjectPoolsVContainerTests.cs.meta +11 -0
- package/Tests/Runtime/Integrations/Zenject/RelationalComponentsZenjectTests.cs +255 -227
- package/Tests/Runtime/Performance/SpatialTree2DPerformanceTests.cs +5 -0
- package/Tests/Runtime/Performance/SpatialTree3DPerformanceTests.cs +3 -0
- package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs +30 -0
- package/Tests/Runtime/Serialization/JsonConverterAdditionalTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/JsonConverterTests.cs +8 -12
- package/Tests/Runtime/Serialization/JsonSerializationTest.cs +16 -5
- package/Tests/Runtime/Serialization/SerializerAdditionalTests.cs +12 -0
- package/Tests/Runtime/Serialization/SerializerFileIoTests.cs +105 -0
- package/Tests/Runtime/Serialization/SerializerFileIoTests.cs.meta +11 -0
- package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs +247 -0
- package/Tests/Runtime/Serialization/UnityEngineObjectJsonTests.cs.meta +11 -0
- package/Tests/Runtime/TestUtils/CommonTestBase.cs +88 -0
- package/Tests/Runtime/Utils/CoroutineHandlerTests.cs +1 -1
- package/Tests/Runtime/Utils/LZMAComprehensiveTests.cs +1 -1
- package/Tests/Runtime/Utils/LZMATests.cs +1 -1
- package/Tests/Runtime/Utils/MatchColliderToSpriteTests.cs +1 -1
- package/Tests/Runtime/Visuals/EnhancedImageTests.cs +25 -56
- package/Tests/Runtime/Visuals/VisualsTestHelpers.cs +1 -8
- package/package-lock.json.meta +7 -0
- package/package.json +8 -4
- package/scripts/check-eol.ps1 +4 -5
- package/scripts/lint-tests.ps1 +156 -0
- package/scripts/lint-tests.ps1.meta +7 -0
- package/scripts/normalize-eol.ps1 +6 -9
- package/.github/workflows/csharpier.yml +0 -135
|
@@ -5,7 +5,6 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
5
5
|
using UnityEngine;
|
|
6
6
|
using UnityEditor;
|
|
7
7
|
using System.Collections.Generic;
|
|
8
|
-
using System.Linq;
|
|
9
8
|
using System.IO;
|
|
10
9
|
using UnityEngine.Serialization;
|
|
11
10
|
using WallstopStudios.UnityHelpers.Core.Helper;
|
|
@@ -119,12 +118,29 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
119
118
|
string[] guids = AssetDatabase.FindAssets(
|
|
120
119
|
"t:" + nameof(PersistentDirectorySettings)
|
|
121
120
|
);
|
|
122
|
-
List<string> candidatePaths =
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
List<string> candidatePaths = new();
|
|
122
|
+
using (
|
|
123
|
+
WallstopStudios
|
|
124
|
+
.UnityHelpers.Utils.SetBuffers<string>.GetHashSetPool(
|
|
125
|
+
StringComparer.OrdinalIgnoreCase
|
|
126
|
+
)
|
|
127
|
+
.Get(out HashSet<string> seen)
|
|
128
|
+
)
|
|
129
|
+
{
|
|
130
|
+
for (int i = 0; i < guids.Length; i++)
|
|
131
|
+
{
|
|
132
|
+
string path = AssetDatabase.GUIDToAssetPath(guids[i]);
|
|
133
|
+
if (string.IsNullOrWhiteSpace(path))
|
|
134
|
+
{
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
string sanitized = SanitizePath(path);
|
|
138
|
+
if (seen.Add(sanitized))
|
|
139
|
+
{
|
|
140
|
+
candidatePaths.Add(sanitized);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
128
144
|
|
|
129
145
|
PersistentDirectorySettings target =
|
|
130
146
|
AssetDatabase.LoadAssetAtPath<PersistentDirectorySettings>(targetAssetPath);
|
|
@@ -292,12 +308,48 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
292
308
|
return Array.Empty<DirectoryUsageData>();
|
|
293
309
|
}
|
|
294
310
|
|
|
295
|
-
DirectoryUsageData
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
.
|
|
311
|
+
List<DirectoryUsageData> list = context.directories;
|
|
312
|
+
if (list == null || list.Count == 0)
|
|
313
|
+
{
|
|
314
|
+
return Array.Empty<DirectoryUsageData>();
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
DirectoryUsageData[] sortedDirectories = new DirectoryUsageData[list.Count];
|
|
318
|
+
for (int i = 0; i < list.Count; i++)
|
|
319
|
+
{
|
|
320
|
+
sortedDirectories[i] = list[i];
|
|
321
|
+
}
|
|
322
|
+
Array.Sort(
|
|
323
|
+
sortedDirectories,
|
|
324
|
+
static (a, b) =>
|
|
325
|
+
{
|
|
326
|
+
int cmp = b.count.CompareTo(a.count);
|
|
327
|
+
if (cmp != 0)
|
|
328
|
+
{
|
|
329
|
+
return cmp;
|
|
330
|
+
}
|
|
331
|
+
return b.lastUsedTicks.CompareTo(a.lastUsedTicks);
|
|
332
|
+
}
|
|
333
|
+
);
|
|
299
334
|
|
|
300
|
-
|
|
335
|
+
if (topOnly)
|
|
336
|
+
{
|
|
337
|
+
int n =
|
|
338
|
+
topN < 0
|
|
339
|
+
? 0
|
|
340
|
+
: (topN > sortedDirectories.Length ? sortedDirectories.Length : topN);
|
|
341
|
+
if (n == sortedDirectories.Length)
|
|
342
|
+
{
|
|
343
|
+
return sortedDirectories;
|
|
344
|
+
}
|
|
345
|
+
DirectoryUsageData[] result = new DirectoryUsageData[n];
|
|
346
|
+
for (int i = 0; i < n; i++)
|
|
347
|
+
{
|
|
348
|
+
result[i] = sortedDirectories[i];
|
|
349
|
+
}
|
|
350
|
+
return result;
|
|
351
|
+
}
|
|
352
|
+
return sortedDirectories;
|
|
301
353
|
}
|
|
302
354
|
|
|
303
355
|
private static void MergeSettings(
|
package/Editor/PrefabChecker.cs
CHANGED
|
@@ -6,7 +6,6 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
6
6
|
using System.Collections.Generic;
|
|
7
7
|
using System.Diagnostics;
|
|
8
8
|
using System.IO;
|
|
9
|
-
using System.Linq;
|
|
10
9
|
using System.Reflection;
|
|
11
10
|
using UnityEditor;
|
|
12
11
|
using UnityEditorInternal;
|
|
@@ -117,6 +116,10 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
117
116
|
{
|
|
118
117
|
ExportLastReport();
|
|
119
118
|
}
|
|
119
|
+
if (GUILayout.Button("Export Report (CSV)"))
|
|
120
|
+
{
|
|
121
|
+
ExportLastReportCsv();
|
|
122
|
+
}
|
|
120
123
|
}
|
|
121
124
|
}
|
|
122
125
|
finally
|
|
@@ -1267,18 +1270,31 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
1267
1270
|
}
|
|
1268
1271
|
|
|
1269
1272
|
[Serializable]
|
|
1270
|
-
|
|
1273
|
+
internal sealed class ScanReport
|
|
1271
1274
|
{
|
|
1272
1275
|
public readonly string[] folders;
|
|
1273
1276
|
public readonly List<Item> items = new();
|
|
1274
1277
|
|
|
1275
1278
|
public ScanReport(IEnumerable<string> folders)
|
|
1276
1279
|
{
|
|
1277
|
-
|
|
1280
|
+
if (folders == null)
|
|
1281
|
+
{
|
|
1282
|
+
this.folders = Array.Empty<string>();
|
|
1283
|
+
return;
|
|
1284
|
+
}
|
|
1285
|
+
// Manual copy to avoid LINQ
|
|
1286
|
+
using (Buffers<string>.List.Get(out List<string> list))
|
|
1287
|
+
{
|
|
1288
|
+
foreach (string s in folders)
|
|
1289
|
+
{
|
|
1290
|
+
list.Add(s);
|
|
1291
|
+
}
|
|
1292
|
+
this.folders = list.ToArray();
|
|
1293
|
+
}
|
|
1278
1294
|
}
|
|
1279
1295
|
|
|
1280
1296
|
[Serializable]
|
|
1281
|
-
|
|
1297
|
+
internal sealed class Item
|
|
1282
1298
|
{
|
|
1283
1299
|
public string path;
|
|
1284
1300
|
public string[] messages;
|
|
@@ -1286,7 +1302,11 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
1286
1302
|
|
|
1287
1303
|
public void Add(string path, List<string> messages)
|
|
1288
1304
|
{
|
|
1289
|
-
|
|
1305
|
+
string[] arr =
|
|
1306
|
+
messages != null && messages.Count > 0
|
|
1307
|
+
? messages.ToArray()
|
|
1308
|
+
: Array.Empty<string>();
|
|
1309
|
+
items.Add(new Item { path = path, messages = arr });
|
|
1290
1310
|
}
|
|
1291
1311
|
}
|
|
1292
1312
|
|
|
@@ -1324,6 +1344,53 @@ namespace WallstopStudios.UnityHelpers.Editor
|
|
|
1324
1344
|
this.LogError($"Failed to save report: {e.Message}");
|
|
1325
1345
|
}
|
|
1326
1346
|
}
|
|
1347
|
+
|
|
1348
|
+
private void ExportLastReportCsv()
|
|
1349
|
+
{
|
|
1350
|
+
if (_lastReport == null || _lastReport.items.Count == 0)
|
|
1351
|
+
{
|
|
1352
|
+
EditorUi.Info("Prefab Checker", "No report data to export.");
|
|
1353
|
+
return;
|
|
1354
|
+
}
|
|
1355
|
+
string defaultPath = Application.dataPath + "/PrefabCheckerReport.csv";
|
|
1356
|
+
string savePath = EditorUi.Suppress
|
|
1357
|
+
? defaultPath
|
|
1358
|
+
: EditorUtility.SaveFilePanel(
|
|
1359
|
+
"Save Prefab Checker Report (CSV)",
|
|
1360
|
+
Application.dataPath,
|
|
1361
|
+
"PrefabCheckerReport",
|
|
1362
|
+
"csv"
|
|
1363
|
+
);
|
|
1364
|
+
if (string.IsNullOrWhiteSpace(savePath))
|
|
1365
|
+
{
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
try
|
|
1370
|
+
{
|
|
1371
|
+
using StreamWriter sw = new(savePath);
|
|
1372
|
+
sw.WriteLine("Path,Message");
|
|
1373
|
+
foreach (ScanReport.Item item in _lastReport.items)
|
|
1374
|
+
{
|
|
1375
|
+
string path = item.path?.Replace('"', '\'') ?? string.Empty;
|
|
1376
|
+
if (item.messages == null || item.messages.Length == 0)
|
|
1377
|
+
{
|
|
1378
|
+
sw.WriteLine($"\"{path}\",\"\"");
|
|
1379
|
+
continue;
|
|
1380
|
+
}
|
|
1381
|
+
foreach (string m in item.messages)
|
|
1382
|
+
{
|
|
1383
|
+
string msg = (m ?? string.Empty).Replace('"', '\'');
|
|
1384
|
+
sw.WriteLine($"\"{path}\",\"{msg}\"");
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
this.Log($"Saved report to: {savePath}");
|
|
1388
|
+
}
|
|
1389
|
+
catch (Exception e)
|
|
1390
|
+
{
|
|
1391
|
+
this.LogError($"Failed to save CSV: {e.Message}");
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1327
1394
|
}
|
|
1328
1395
|
#endif
|
|
1329
1396
|
}
|
|
@@ -119,16 +119,16 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
119
119
|
private bool _unchangedFoldout;
|
|
120
120
|
private bool _orphansFoldout;
|
|
121
121
|
private Vector2 _previewScroll;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
122
|
+
internal string _filterText = string.Empty;
|
|
123
|
+
internal bool _filterUseRegex;
|
|
124
|
+
internal bool _sortAscending = true;
|
|
125
125
|
|
|
126
|
-
|
|
126
|
+
public enum AnimationStatus
|
|
127
127
|
{
|
|
128
|
-
Unknown,
|
|
129
|
-
New,
|
|
130
|
-
Changed,
|
|
131
|
-
Unchanged,
|
|
128
|
+
Unknown = 0,
|
|
129
|
+
New = 1,
|
|
130
|
+
Changed = 2,
|
|
131
|
+
Unchanged = 3,
|
|
132
132
|
}
|
|
133
133
|
|
|
134
134
|
internal enum CopyMode
|
|
@@ -138,7 +138,7 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
138
138
|
New,
|
|
139
139
|
}
|
|
140
140
|
|
|
141
|
-
|
|
141
|
+
internal sealed class AnimationFileInfo
|
|
142
142
|
{
|
|
143
143
|
public string RelativePath { get; set; }
|
|
144
144
|
public string FullPath { get; set; }
|
|
@@ -291,12 +291,37 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
291
291
|
bool canAnalyze = ArePathsValid();
|
|
292
292
|
bool analysisDone = !_analysisNeeded;
|
|
293
293
|
|
|
294
|
-
int selectedNew =
|
|
295
|
-
|
|
294
|
+
int selectedNew = 0;
|
|
295
|
+
foreach (AnimationFileInfo newAnimation in _newAnimations)
|
|
296
|
+
{
|
|
297
|
+
if (newAnimation.Selected)
|
|
298
|
+
{
|
|
299
|
+
++selectedNew;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
int selectedChanged = 0;
|
|
304
|
+
foreach (AnimationFileInfo changedAnimation in _changedAnimations)
|
|
305
|
+
{
|
|
306
|
+
if (changedAnimation.Selected)
|
|
307
|
+
{
|
|
308
|
+
++selectedChanged;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
int selectedUnchanged = 0;
|
|
313
|
+
foreach (AnimationFileInfo unchangedAnimation in _unchangedAnimations)
|
|
314
|
+
{
|
|
315
|
+
if (unchangedAnimation.Selected)
|
|
316
|
+
{
|
|
317
|
+
++selectedUnchanged;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
296
321
|
int selectedAll =
|
|
297
322
|
selectedNew
|
|
298
323
|
+ selectedChanged
|
|
299
|
-
+ (_includeUnchangedInCopyAll ?
|
|
324
|
+
+ (_includeUnchangedInCopyAll ? selectedUnchanged : 0);
|
|
300
325
|
|
|
301
326
|
bool canCopyNew = canAnalyze && analysisDone && selectedNew > 0;
|
|
302
327
|
bool canCopyChanged = canAnalyze && analysisDone && selectedChanged > 0;
|
|
@@ -342,14 +367,8 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
342
367
|
if (GUILayout.Button($"Copy All ({totalToCopyAll})"))
|
|
343
368
|
{
|
|
344
369
|
string overwriteWarning =
|
|
345
|
-
selectedChanged
|
|
346
|
-
+ (
|
|
347
|
-
_includeUnchangedInCopyAll
|
|
348
|
-
? _unchangedAnimations.Count(a => a.Selected)
|
|
349
|
-
: 0
|
|
350
|
-
)
|
|
351
|
-
> 0
|
|
352
|
-
? $" This will overwrite {selectedChanged + (_includeUnchangedInCopyAll ? _unchangedAnimations.Count(a => a.Selected) : 0)} existing files."
|
|
370
|
+
selectedChanged + (_includeUnchangedInCopyAll ? selectedUnchanged : 0) > 0
|
|
371
|
+
? $" This will overwrite {selectedChanged + (_includeUnchangedInCopyAll ? selectedUnchanged : 0)} existing files."
|
|
353
372
|
: "";
|
|
354
373
|
if (
|
|
355
374
|
Confirm(
|
|
@@ -372,8 +391,8 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
372
391
|
|
|
373
392
|
bool canAnalyze = ArePathsValid();
|
|
374
393
|
bool analysisDone = !_analysisNeeded;
|
|
375
|
-
bool hasUnchanged = _unchangedAnimations.
|
|
376
|
-
bool hasOrphans = _destinationOrphans.
|
|
394
|
+
bool hasUnchanged = _unchangedAnimations.Count > 0;
|
|
395
|
+
bool hasOrphans = _destinationOrphans.Count > 0;
|
|
377
396
|
|
|
378
397
|
_dryRun = EditorGUILayout.ToggleLeft("Dry Run (no changes)", _dryRun);
|
|
379
398
|
|
|
@@ -943,9 +962,15 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
943
962
|
return;
|
|
944
963
|
}
|
|
945
964
|
|
|
946
|
-
List<AnimationFileInfo> animationsToDelete =
|
|
947
|
-
|
|
948
|
-
|
|
965
|
+
List<AnimationFileInfo> animationsToDelete = new List<AnimationFileInfo>();
|
|
966
|
+
for (int i = 0; i < _unchangedAnimations.Count; i++)
|
|
967
|
+
{
|
|
968
|
+
AnimationFileInfo a = _unchangedAnimations[i];
|
|
969
|
+
if (a != null && a.Selected)
|
|
970
|
+
{
|
|
971
|
+
animationsToDelete.Add(a);
|
|
972
|
+
}
|
|
973
|
+
}
|
|
949
974
|
|
|
950
975
|
if (animationsToDelete.Count == 0)
|
|
951
976
|
{
|
|
@@ -1192,9 +1217,8 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1192
1217
|
return;
|
|
1193
1218
|
}
|
|
1194
1219
|
IEnumerable<AnimationFileInfo> filtered = ApplyFilterAndSort(items);
|
|
1195
|
-
AnimationFileInfo
|
|
1196
|
-
|
|
1197
|
-
int count = animationFileInfos.Length;
|
|
1220
|
+
IList<AnimationFileInfo> animationFileInfos = filtered.AsList();
|
|
1221
|
+
int count = animationFileInfos.Count;
|
|
1198
1222
|
if (count == 0)
|
|
1199
1223
|
{
|
|
1200
1224
|
using (new EditorGUILayout.HorizontalScope())
|
|
@@ -1217,36 +1241,41 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1217
1241
|
{
|
|
1218
1242
|
if (GUILayout.Button("Select All", GUILayout.Width(100)))
|
|
1219
1243
|
{
|
|
1220
|
-
|
|
1244
|
+
for (int i = 0; i < animationFileInfos.Count; i++)
|
|
1221
1245
|
{
|
|
1246
|
+
AnimationFileInfo info = animationFileInfos[i];
|
|
1222
1247
|
info.Selected = true;
|
|
1223
1248
|
}
|
|
1224
1249
|
}
|
|
1225
1250
|
if (GUILayout.Button("Select None", GUILayout.Width(100)))
|
|
1226
1251
|
{
|
|
1227
|
-
|
|
1252
|
+
for (int i = 0; i < animationFileInfos.Count; i++)
|
|
1228
1253
|
{
|
|
1254
|
+
AnimationFileInfo info = animationFileInfos[i];
|
|
1229
1255
|
info.Selected = false;
|
|
1230
1256
|
}
|
|
1231
1257
|
}
|
|
1232
1258
|
if (GUILayout.Button("Select Filtered", GUILayout.Width(120)))
|
|
1233
1259
|
{
|
|
1234
|
-
|
|
1260
|
+
for (int i = 0; i < animationFileInfos.Count; i++)
|
|
1235
1261
|
{
|
|
1262
|
+
AnimationFileInfo info = animationFileInfos[i];
|
|
1236
1263
|
info.Selected = true;
|
|
1237
1264
|
}
|
|
1238
1265
|
}
|
|
1239
1266
|
if (GUILayout.Button("Clear Filtered", GUILayout.Width(120)))
|
|
1240
1267
|
{
|
|
1241
|
-
|
|
1268
|
+
for (int i = 0; i < animationFileInfos.Count; i++)
|
|
1242
1269
|
{
|
|
1270
|
+
AnimationFileInfo info = animationFileInfos[i];
|
|
1243
1271
|
info.Selected = false;
|
|
1244
1272
|
}
|
|
1245
1273
|
}
|
|
1246
1274
|
}
|
|
1247
1275
|
|
|
1248
|
-
|
|
1276
|
+
for (int i = 0; i < animationFileInfos.Count; i++)
|
|
1249
1277
|
{
|
|
1278
|
+
AnimationFileInfo info = animationFileInfos[i];
|
|
1250
1279
|
using (new EditorGUILayout.HorizontalScope())
|
|
1251
1280
|
{
|
|
1252
1281
|
info.Selected = EditorGUILayout.Toggle(info.Selected, GUILayout.Width(20));
|
|
@@ -1272,38 +1301,77 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1272
1301
|
}
|
|
1273
1302
|
}
|
|
1274
1303
|
|
|
1275
|
-
|
|
1304
|
+
internal IEnumerable<AnimationFileInfo> ApplyFilterAndSort(List<AnimationFileInfo> items)
|
|
1276
1305
|
{
|
|
1277
|
-
|
|
1278
|
-
|
|
1306
|
+
if (items == null || items.Count == 0)
|
|
1307
|
+
{
|
|
1308
|
+
yield break;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
using (Buffers<AnimationFileInfo>.List.Get(out List<AnimationFileInfo> filtered))
|
|
1279
1312
|
{
|
|
1280
|
-
if (
|
|
1313
|
+
if (string.IsNullOrWhiteSpace(_filterText))
|
|
1314
|
+
{
|
|
1315
|
+
for (int i = 0; i < items.Count; i++)
|
|
1316
|
+
{
|
|
1317
|
+
AnimationFileInfo it = items[i];
|
|
1318
|
+
if (it != null)
|
|
1319
|
+
{
|
|
1320
|
+
filtered.Add(it);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
}
|
|
1324
|
+
else if (_filterUseRegex)
|
|
1281
1325
|
{
|
|
1282
1326
|
try
|
|
1283
1327
|
{
|
|
1284
|
-
Regex rx = new(_filterText, RegexOptions.IgnoreCase);
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1328
|
+
Regex rx = new Regex(_filterText, RegexOptions.IgnoreCase);
|
|
1329
|
+
for (int i = 0; i < items.Count; i++)
|
|
1330
|
+
{
|
|
1331
|
+
AnimationFileInfo it = items[i];
|
|
1332
|
+
if (it != null && it.FileName != null && rx.IsMatch(it.FileName))
|
|
1333
|
+
{
|
|
1334
|
+
filtered.Add(it);
|
|
1335
|
+
}
|
|
1336
|
+
}
|
|
1288
1337
|
}
|
|
1289
1338
|
catch (Exception ex)
|
|
1290
1339
|
{
|
|
1291
1340
|
this.LogWarn($"Invalid regex '{_filterText}': {ex.Message}");
|
|
1292
|
-
query = Enumerable.Empty<AnimationFileInfo>();
|
|
1293
1341
|
}
|
|
1294
1342
|
}
|
|
1295
1343
|
else
|
|
1296
1344
|
{
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1345
|
+
for (int i = 0; i < items.Count; i++)
|
|
1346
|
+
{
|
|
1347
|
+
AnimationFileInfo it = items[i];
|
|
1348
|
+
if (
|
|
1349
|
+
it != null
|
|
1350
|
+
&& it.FileName != null
|
|
1351
|
+
&& it.FileName.IndexOf(_filterText, StringComparison.OrdinalIgnoreCase)
|
|
1352
|
+
>= 0
|
|
1353
|
+
)
|
|
1354
|
+
{
|
|
1355
|
+
filtered.Add(it);
|
|
1356
|
+
}
|
|
1357
|
+
}
|
|
1358
|
+
}
|
|
1359
|
+
|
|
1360
|
+
filtered.Sort(
|
|
1361
|
+
(a, b) =>
|
|
1362
|
+
{
|
|
1363
|
+
string an = a?.FileName ?? string.Empty;
|
|
1364
|
+
string bn = b?.FileName ?? string.Empty;
|
|
1365
|
+
int cmp = string.Compare(an, bn, StringComparison.OrdinalIgnoreCase);
|
|
1366
|
+
return _sortAscending ? cmp : -cmp;
|
|
1367
|
+
}
|
|
1368
|
+
);
|
|
1369
|
+
|
|
1370
|
+
for (int i = 0; i < filtered.Count; i++)
|
|
1371
|
+
{
|
|
1372
|
+
yield return filtered[i];
|
|
1301
1373
|
}
|
|
1302
1374
|
}
|
|
1303
|
-
query = _sortAscending
|
|
1304
|
-
? query.OrderBy(i => i.FileName, StringComparer.OrdinalIgnoreCase)
|
|
1305
|
-
: query.OrderByDescending(i => i.FileName, StringComparer.OrdinalIgnoreCase);
|
|
1306
|
-
return query;
|
|
1307
1375
|
}
|
|
1308
1376
|
|
|
1309
1377
|
internal void MirrorDeleteDestinationAnimations()
|
|
@@ -1313,9 +1381,15 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1313
1381
|
return;
|
|
1314
1382
|
}
|
|
1315
1383
|
|
|
1316
|
-
List<AnimationFileInfo> toDelete =
|
|
1317
|
-
|
|
1318
|
-
|
|
1384
|
+
List<AnimationFileInfo> toDelete = new List<AnimationFileInfo>();
|
|
1385
|
+
for (int i = 0; i < _destinationOrphans.Count; i++)
|
|
1386
|
+
{
|
|
1387
|
+
AnimationFileInfo a = _destinationOrphans[i];
|
|
1388
|
+
if (a != null && a.Selected)
|
|
1389
|
+
{
|
|
1390
|
+
toDelete.Add(a);
|
|
1391
|
+
}
|
|
1392
|
+
}
|
|
1319
1393
|
if (toDelete.Count == 0)
|
|
1320
1394
|
{
|
|
1321
1395
|
Info("Nothing to Delete", "No destination orphans are selected.");
|
|
@@ -1456,15 +1530,17 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1456
1530
|
bool useSource
|
|
1457
1531
|
)
|
|
1458
1532
|
{
|
|
1459
|
-
|
|
1460
|
-
sb.AppendLine($"== {inputTitle} ({arr.
|
|
1461
|
-
|
|
1533
|
+
var arr = ApplyFilterAndSort(list.ToList()).AsList();
|
|
1534
|
+
sb.AppendLine($"== {inputTitle} ({arr.Count}) ==");
|
|
1535
|
+
for (int i = 0; i < arr.Count; i++)
|
|
1462
1536
|
{
|
|
1537
|
+
AnimationFileInfo info = arr[i];
|
|
1463
1538
|
string path = useSource ? info.RelativePath : info.DestinationRelativePath;
|
|
1464
1539
|
sb.AppendLine(
|
|
1465
1540
|
$"[{(info.Selected ? 'x' : ' ')}] {info.FileName} -> {path}"
|
|
1466
1541
|
);
|
|
1467
1542
|
}
|
|
1543
|
+
|
|
1468
1544
|
sb.AppendLine();
|
|
1469
1545
|
}
|
|
1470
1546
|
|
|
@@ -4,7 +4,6 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
4
4
|
using System;
|
|
5
5
|
using System.Collections.Generic;
|
|
6
6
|
using System.IO;
|
|
7
|
-
using System.Linq;
|
|
8
7
|
using System.Text.RegularExpressions;
|
|
9
8
|
using UnityEditor;
|
|
10
9
|
using UnityEngine;
|
|
@@ -485,9 +484,17 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
485
484
|
bool matchesSearch = true;
|
|
486
485
|
if (searchTerms.Length > 0)
|
|
487
486
|
{
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
487
|
+
for (int si = 0; si < searchTerms.Length; si++)
|
|
488
|
+
{
|
|
489
|
+
if (
|
|
490
|
+
currentName.IndexOf(searchTerms[si], StringComparison.OrdinalIgnoreCase)
|
|
491
|
+
< 0
|
|
492
|
+
)
|
|
493
|
+
{
|
|
494
|
+
matchesSearch = false;
|
|
495
|
+
break;
|
|
496
|
+
}
|
|
497
|
+
}
|
|
491
498
|
}
|
|
492
499
|
|
|
493
500
|
if (matchesSearch)
|
|
@@ -614,10 +621,21 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
614
621
|
);
|
|
615
622
|
}
|
|
616
623
|
|
|
617
|
-
bool canBulkName =
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
624
|
+
bool canBulkName = animationData is { Count: > 0 } && !string.IsNullOrWhiteSpace(text);
|
|
625
|
+
if (canBulkName)
|
|
626
|
+
{
|
|
627
|
+
bool anyFrames = false;
|
|
628
|
+
for (int i = 0; i < animationData.Count; i++)
|
|
629
|
+
{
|
|
630
|
+
List<Sprite> fr = animationData[i]?.frames;
|
|
631
|
+
if (fr != null && fr.Count > 0)
|
|
632
|
+
{
|
|
633
|
+
anyFrames = true;
|
|
634
|
+
break;
|
|
635
|
+
}
|
|
636
|
+
}
|
|
637
|
+
canBulkName = anyFrames;
|
|
638
|
+
}
|
|
621
639
|
|
|
622
640
|
using (new EditorGUI.DisabledScope(!canBulkName))
|
|
623
641
|
{
|
|
@@ -694,16 +712,25 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
694
712
|
}
|
|
695
713
|
}
|
|
696
714
|
|
|
697
|
-
if (
|
|
698
|
-
!canBulkName
|
|
699
|
-
&& animationData is { Count: > 0 }
|
|
700
|
-
&& animationData.Any(data => data.frames?.Count > 0)
|
|
701
|
-
)
|
|
715
|
+
if (!canBulkName && animationData is { Count: > 0 })
|
|
702
716
|
{
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
717
|
+
bool anyFrames = false;
|
|
718
|
+
for (int i = 0; i < animationData.Count; i++)
|
|
719
|
+
{
|
|
720
|
+
List<Sprite> fr = animationData[i]?.frames;
|
|
721
|
+
if (fr != null && fr.Count > 0)
|
|
722
|
+
{
|
|
723
|
+
anyFrames = true;
|
|
724
|
+
break;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
if (anyFrames)
|
|
728
|
+
{
|
|
729
|
+
EditorGUILayout.HelpBox(
|
|
730
|
+
"Enter text in the 'Text' field above to enable bulk naming operations.",
|
|
731
|
+
MessageType.Info
|
|
732
|
+
);
|
|
733
|
+
}
|
|
707
734
|
}
|
|
708
735
|
|
|
709
736
|
EditorGUILayout.Space();
|
|
@@ -747,7 +774,16 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
747
774
|
foreach (AnimationData data in animationData)
|
|
748
775
|
{
|
|
749
776
|
string lowerName = (data.animationName ?? string.Empty).ToLowerInvariant();
|
|
750
|
-
|
|
777
|
+
bool allMatch = true;
|
|
778
|
+
for (int i = 0; i < searchTerms.Length; i++)
|
|
779
|
+
{
|
|
780
|
+
if (lowerName.IndexOf(searchTerms[i], StringComparison.Ordinal) < 0)
|
|
781
|
+
{
|
|
782
|
+
allMatch = false;
|
|
783
|
+
break;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
if (allMatch)
|
|
751
787
|
{
|
|
752
788
|
dataToCreate.Add(data);
|
|
753
789
|
}
|
|
@@ -987,8 +1023,13 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
987
1023
|
}
|
|
988
1024
|
|
|
989
1025
|
List<string> searchPaths = new();
|
|
990
|
-
|
|
1026
|
+
for (int i = 0; i < animationSources.Count; i++)
|
|
991
1027
|
{
|
|
1028
|
+
Object source = animationSources[i];
|
|
1029
|
+
if (source == null)
|
|
1030
|
+
{
|
|
1031
|
+
continue;
|
|
1032
|
+
}
|
|
992
1033
|
string path = AssetDatabase.GetAssetPath(source);
|
|
993
1034
|
if (!string.IsNullOrWhiteSpace(path) && AssetDatabase.IsValidFolder(path))
|
|
994
1035
|
{
|
|
@@ -1291,7 +1332,7 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1291
1332
|
continue;
|
|
1292
1333
|
}
|
|
1293
1334
|
|
|
1294
|
-
bool hasAnyIndex = entries.
|
|
1335
|
+
bool hasAnyIndex = entries.Exists(e => e.index >= 0);
|
|
1295
1336
|
if (strictNumericOrdering)
|
|
1296
1337
|
{
|
|
1297
1338
|
if (hasAnyIndex)
|
|
@@ -1445,7 +1486,7 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1445
1486
|
string dir = kvp.Key;
|
|
1446
1487
|
foreach ((string baseKey, List<(int index, Sprite sprite)> entries) in kvp.Value)
|
|
1447
1488
|
{
|
|
1448
|
-
bool hasAnyIndex = entries.
|
|
1489
|
+
bool hasAnyIndex = entries.Exists(e => e.index >= 0);
|
|
1449
1490
|
if (strictNumericOrdering)
|
|
1450
1491
|
{
|
|
1451
1492
|
if (hasAnyIndex)
|
|
@@ -1517,7 +1558,7 @@ namespace WallstopStudios.UnityHelpers.Editor.Sprites
|
|
|
1517
1558
|
folder = folderName,
|
|
1518
1559
|
baseName = baseKey,
|
|
1519
1560
|
count = entries.Count,
|
|
1520
|
-
hasIndex = entries.
|
|
1561
|
+
hasIndex = entries.Exists(e => e.index >= 0),
|
|
1521
1562
|
};
|
|
1522
1563
|
_autoParsePreview.Add(rec);
|
|
1523
1564
|
}
|