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.
- package/Editor/{Sprites/AnimationCopier.cs → AnimationCopier.cs} +209 -84
- package/Editor/{Sprites/AnimationCreator.cs → AnimationCreator.cs} +100 -29
- package/Editor/AnimationEventEditor.cs +23 -10
- package/Editor/CustomEditors/MatchColliderToSpriteEditor.cs +1 -1
- package/Editor/FitTextureSizeWindow.cs +53 -14
- package/Editor/PrefabChecker.cs +18 -11
- package/Editor/SpriteAtlasGenerator.cs +914 -0
- package/Editor/SpriteAtlasGenerator.cs.meta +3 -0
- package/Editor/{Sprites/SpriteCropper.cs → SpriteCropper.cs} +143 -172
- package/Editor/{Sprites/SpriteSettingsApplier.cs → SpriteSettingsApplier.cs} +77 -12
- package/Editor/{Sprites/TextureResizerWizard.cs → TextureResizerWizard.cs} +1 -1
- package/Editor/{Sprites/TextureSettingsApplier.cs → TextureSettingsApplier.cs} +1 -1
- package/Editor/Utils/DxReadOnlyPropertyDrawer.cs +1 -1
- package/Editor/Utils/GUIHorizontalScope.cs +20 -0
- package/Editor/Utils/GUIHorizontalScope.cs.meta +3 -0
- package/Runtime/Core/DataStructure/Circle.cs +1 -1
- package/Runtime/Core/DataStructure/QuadTree.cs +4 -4
- package/Runtime/Core/Extension/ColorExtensions.cs +5 -5
- package/Runtime/Core/Extension/IEnumerableExtensions.cs +1 -1
- package/Runtime/Core/Extension/UnityExtensions.cs +14 -14
- package/Runtime/Core/Helper/DirectoryHelper.cs +0 -64
- package/Runtime/Core/Helper/Helpers.cs +9 -9
- package/Runtime/Core/Helper/Logging/UnityLogTagFormatter.cs +8 -31
- package/Runtime/Core/Helper/Partials/ObjectHelpers.cs +4 -5
- package/Runtime/Core/Helper/PathHelper.cs +1 -2
- package/Runtime/Core/Random/DotNetRandom.cs +1 -1
- package/Runtime/Core/Random/SplitMix64.cs +1 -1
- package/Runtime/Core/Random/SquirrelRandom.cs +7 -7
- package/Runtime/Core/Random/ThreadLocalRandom.cs +1 -1
- package/Runtime/Core/Random/WyRandom.cs +1 -1
- package/Runtime/Tags/AttributeEffect.cs +0 -1
- package/Runtime/Tags/EffectHandler.cs +1 -1
- package/Runtime/UI/LayeredImage.cs +161 -309
- package/Runtime/Utils/AnimatorEnumStateMachine.cs +1 -1
- package/Runtime/Utils/SetTextureImportData.cs +1 -1
- package/Runtime/Utils/TextureScale.cs +4 -4
- package/Styles/Elements/{Progress/CircularProgressBar.cs → CircularProgressBar.cs} +55 -56
- package/Styles/Elements/{Progress/RegularProgressBar.cs → RegularProgressBar.cs} +13 -24
- package/Styles/UXML/CircularProgressBar.uxml +11 -0
- package/Styles/UXML/CircularProgressBar.uxml.meta +10 -0
- package/Styles/UXML/RegularProgressBar.uxml +22 -0
- package/Styles/UXML/RegularProgressBar.uxml.meta +10 -0
- package/Styles/UXML.meta +3 -0
- package/package.json +1 -17
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs +0 -796
- package/Editor/CustomEditors/PersistentDirectoryGUI.cs.meta +0 -3
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs +0 -275
- package/Editor/CustomEditors/SourceFolderEntryDrawer.cs.meta +0 -3
- package/Editor/PersistentDirectorySettings.cs +0 -248
- package/Editor/PersistentDirectorySettings.cs.meta +0 -3
- package/Editor/Sprites/ScriptableSpriteAtlas.cs +0 -95
- package/Editor/Sprites/ScriptableSpriteAtlas.cs.meta +0 -3
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs +0 -960
- package/Editor/Sprites/ScriptableSpriteAtlasEditor.cs.meta +0 -3
- package/Editor/Sprites.meta +0 -3
- package/Styles/Elements/Progress/ArcedProgressBar.cs +0 -345
- package/Styles/Elements/Progress/ArcedProgressBar.cs.meta +0 -3
- package/Styles/Elements/Progress/GlitchProgressBar.cs +0 -416
- package/Styles/Elements/Progress/GlitchProgressBar.cs.meta +0 -3
- package/Styles/Elements/Progress/LiquidProgressBar.cs +0 -632
- package/Styles/Elements/Progress/LiquidProgressBar.cs.meta +0 -3
- package/Styles/Elements/Progress/MarchingAntsProgressBar.cs +0 -722
- package/Styles/Elements/Progress/MarchingAntsProgressBar.cs.meta +0 -3
- package/Styles/Elements/Progress/WigglyProgressBar.cs +0 -837
- package/Styles/Elements/Progress/WigglyProgressBar.cs.meta +0 -3
- package/Styles/Elements/Progress.meta +0 -3
- package/Styles/USS/ArcedProgressBar.uss +0 -19
- package/Styles/USS/ArcedProgressBar.uss.meta +0 -3
- package/Styles/USS/WigglyProgressBar.uss +0 -17
- package/Styles/USS/WigglyProgressBar.uss.meta +0 -3
- /package/Editor/{Sprites/AnimationCopier.cs.meta → AnimationCopier.cs.meta} +0 -0
- /package/Editor/{Sprites/AnimationCreator.cs.meta → AnimationCreator.cs.meta} +0 -0
- /package/Editor/{Sprites/SpriteCropper.cs.meta → SpriteCropper.cs.meta} +0 -0
- /package/Editor/{Sprites/SpriteSettingsApplier.cs.meta → SpriteSettingsApplier.cs.meta} +0 -0
- /package/Editor/{Sprites/TextureResizerWizard.cs.meta → TextureResizerWizard.cs.meta} +0 -0
- /package/Editor/{Sprites/TextureSettingsApplier.cs.meta → TextureSettingsApplier.cs.meta} +0 -0
- /package/Styles/Elements/{Progress/CircularProgressBar.cs.meta → CircularProgressBar.cs.meta} +0 -0
- /package/Styles/Elements/{Progress/RegularProgressBar.cs.meta → RegularProgressBar.cs.meta} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
namespace WallstopStudios.UnityHelpers.Editor
|
|
1
|
+
namespace WallstopStudios.UnityHelpers.Editor
|
|
2
2
|
{
|
|
3
3
|
#if UNITY_EDITOR
|
|
4
4
|
using System;
|
|
@@ -9,16 +9,16 @@
|
|
|
9
9
|
using UnityEditor;
|
|
10
10
|
using UnityEngine;
|
|
11
11
|
using Core.Extension;
|
|
12
|
-
using Core.Helper;
|
|
13
|
-
using CustomEditors;
|
|
14
12
|
|
|
15
13
|
public sealed class AnimationCopierWindow : EditorWindow
|
|
16
14
|
{
|
|
17
|
-
|
|
18
|
-
private string
|
|
15
|
+
private const string SourcePathPrefKey = "AnimationCopier_SourcePathRelative";
|
|
16
|
+
private const string DestPathPrefKey = "AnimationCopier_DestPathRelative";
|
|
17
|
+
private const string DefaultSourcePath = "Assets/Sprites";
|
|
18
|
+
private const string DefaultDestPath = "Assets/Animations";
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
private string _animationDestinationPathRelative = "
|
|
20
|
+
private string _animationSourcePathRelative = "";
|
|
21
|
+
private string _animationDestinationPathRelative = "";
|
|
22
22
|
private string _fullSourcePath = "";
|
|
23
23
|
private string _fullDestinationPath = "";
|
|
24
24
|
|
|
@@ -27,10 +27,6 @@
|
|
|
27
27
|
private bool _isCopying;
|
|
28
28
|
private bool _isDeleting;
|
|
29
29
|
|
|
30
|
-
private SerializedObject _serializedObject;
|
|
31
|
-
private SerializedProperty _animationSourcesPathProperty;
|
|
32
|
-
private SerializedProperty _animationDestinationPathProperty;
|
|
33
|
-
|
|
34
30
|
private readonly List<AnimationFileInfo> _sourceAnimations = new();
|
|
35
31
|
private readonly List<AnimationFileInfo> _newAnimations = new();
|
|
36
32
|
private readonly List<AnimationFileInfo> _changedAnimations = new();
|
|
@@ -62,7 +58,7 @@
|
|
|
62
58
|
public string DestinationRelativePath { get; set; }
|
|
63
59
|
}
|
|
64
60
|
|
|
65
|
-
[MenuItem("Tools/Wallstop Studios/Unity Helpers/Animation Copier", priority = -2)]
|
|
61
|
+
[MenuItem("Tools/Wallstop Studios/Unity Helpers/Animation Copier Window", priority = -2)]
|
|
66
62
|
public static void ShowWindow()
|
|
67
63
|
{
|
|
68
64
|
GetWindow<AnimationCopierWindow>("Animation Copier");
|
|
@@ -70,13 +66,7 @@
|
|
|
70
66
|
|
|
71
67
|
private void OnEnable()
|
|
72
68
|
{
|
|
73
|
-
|
|
74
|
-
_animationSourcesPathProperty = _serializedObject.FindProperty(
|
|
75
|
-
nameof(_animationSourcePathRelative)
|
|
76
|
-
);
|
|
77
|
-
_animationDestinationPathProperty = _serializedObject.FindProperty(
|
|
78
|
-
nameof(_animationDestinationPathRelative)
|
|
79
|
-
);
|
|
69
|
+
LoadPaths();
|
|
80
70
|
ValidatePaths();
|
|
81
71
|
_analysisNeeded = true;
|
|
82
72
|
this.Log($"Animation Copier Window opened.");
|
|
@@ -84,7 +74,6 @@
|
|
|
84
74
|
|
|
85
75
|
private void OnGUI()
|
|
86
76
|
{
|
|
87
|
-
_serializedObject.Update();
|
|
88
77
|
bool operationInProgress = _isAnalyzing || _isCopying || _isDeleting;
|
|
89
78
|
|
|
90
79
|
if (operationInProgress)
|
|
@@ -98,18 +87,18 @@
|
|
|
98
87
|
|
|
99
88
|
EditorGUI.BeginDisabledGroup(operationInProgress);
|
|
100
89
|
|
|
101
|
-
|
|
102
|
-
_animationSourcesPathProperty,
|
|
103
|
-
nameof(AnimationCopierWindow),
|
|
90
|
+
DrawPathSection(
|
|
104
91
|
"Source Path",
|
|
105
|
-
|
|
92
|
+
ref _animationSourcePathRelative,
|
|
93
|
+
ref _fullSourcePath,
|
|
94
|
+
SourcePathPrefKey
|
|
106
95
|
);
|
|
107
96
|
EditorGUILayout.Separator();
|
|
108
|
-
|
|
109
|
-
_animationDestinationPathProperty,
|
|
110
|
-
nameof(AnimationCopierWindow),
|
|
97
|
+
DrawPathSection(
|
|
111
98
|
"Destination Path",
|
|
112
|
-
|
|
99
|
+
ref _animationDestinationPathRelative,
|
|
100
|
+
ref _fullDestinationPath,
|
|
101
|
+
DestPathPrefKey
|
|
113
102
|
);
|
|
114
103
|
EditorGUILayout.Separator();
|
|
115
104
|
|
|
@@ -136,6 +125,85 @@
|
|
|
136
125
|
}
|
|
137
126
|
}
|
|
138
127
|
|
|
128
|
+
private void DrawPathSection(
|
|
129
|
+
string label,
|
|
130
|
+
ref string relativePath,
|
|
131
|
+
ref string fullPath,
|
|
132
|
+
string prefKey
|
|
133
|
+
)
|
|
134
|
+
{
|
|
135
|
+
if (!prefKey.StartsWith("WallstopStudios.UnityHelpers.Editor"))
|
|
136
|
+
{
|
|
137
|
+
prefKey = "WallstopStudios.UnityHelpers.Editor" + prefKey;
|
|
138
|
+
}
|
|
139
|
+
EditorGUILayout.LabelField(label + ":", EditorStyles.boldLabel);
|
|
140
|
+
|
|
141
|
+
EditorGUI.BeginChangeCheck();
|
|
142
|
+
string newRelativePath = EditorGUILayout.TextField(relativePath ?? "");
|
|
143
|
+
if (EditorGUI.EndChangeCheck() && newRelativePath != relativePath)
|
|
144
|
+
{
|
|
145
|
+
if (string.IsNullOrWhiteSpace(newRelativePath))
|
|
146
|
+
{
|
|
147
|
+
relativePath = "";
|
|
148
|
+
fullPath = "";
|
|
149
|
+
EditorPrefs.SetString(prefKey, "");
|
|
150
|
+
ValidatePaths();
|
|
151
|
+
_analysisNeeded = true;
|
|
152
|
+
}
|
|
153
|
+
else
|
|
154
|
+
{
|
|
155
|
+
string tempFullPath = GetFullPathFromRelative(newRelativePath);
|
|
156
|
+
if (tempFullPath != null && Directory.Exists(tempFullPath))
|
|
157
|
+
{
|
|
158
|
+
relativePath = newRelativePath;
|
|
159
|
+
fullPath = tempFullPath;
|
|
160
|
+
EditorPrefs.SetString(prefKey, relativePath);
|
|
161
|
+
ValidatePaths();
|
|
162
|
+
_analysisNeeded = true;
|
|
163
|
+
}
|
|
164
|
+
else
|
|
165
|
+
{
|
|
166
|
+
this.LogWarn(
|
|
167
|
+
$"Manual path entry '{newRelativePath}' is invalid or not inside Assets. Please use the button."
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (GUILayout.Button("Browse..."))
|
|
174
|
+
{
|
|
175
|
+
string initialPath = Directory.Exists(fullPath) ? fullPath : Application.dataPath;
|
|
176
|
+
string selectedPath = EditorUtility.OpenFolderPanel(
|
|
177
|
+
$"Select {label}",
|
|
178
|
+
initialPath,
|
|
179
|
+
string.Empty
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
if (!string.IsNullOrWhiteSpace(selectedPath))
|
|
183
|
+
{
|
|
184
|
+
string newRelPath = GetRelativeAssetPath(selectedPath);
|
|
185
|
+
if (newRelPath != null)
|
|
186
|
+
{
|
|
187
|
+
relativePath = newRelPath;
|
|
188
|
+
fullPath = selectedPath.Replace(Path.DirectorySeparatorChar, '/');
|
|
189
|
+
EditorPrefs.SetString(prefKey, relativePath);
|
|
190
|
+
this.Log($"{label} set to: {relativePath}");
|
|
191
|
+
ValidatePaths();
|
|
192
|
+
_analysisNeeded = true;
|
|
193
|
+
Repaint();
|
|
194
|
+
}
|
|
195
|
+
else
|
|
196
|
+
{
|
|
197
|
+
EditorUtility.DisplayDialog(
|
|
198
|
+
"Invalid Path",
|
|
199
|
+
"The selected path must be inside the project's 'Assets' folder.",
|
|
200
|
+
"OK"
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
139
207
|
private void DrawAnalysisSection()
|
|
140
208
|
{
|
|
141
209
|
EditorGUILayout.LabelField("Analysis:", EditorStyles.boldLabel);
|
|
@@ -270,6 +338,18 @@
|
|
|
270
338
|
}
|
|
271
339
|
}
|
|
272
340
|
|
|
341
|
+
private void LoadPaths()
|
|
342
|
+
{
|
|
343
|
+
_animationSourcePathRelative = EditorPrefs.GetString(
|
|
344
|
+
SourcePathPrefKey,
|
|
345
|
+
DefaultSourcePath
|
|
346
|
+
);
|
|
347
|
+
_animationDestinationPathRelative = EditorPrefs.GetString(
|
|
348
|
+
DestPathPrefKey,
|
|
349
|
+
DefaultDestPath
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
|
|
273
353
|
private void ValidatePaths()
|
|
274
354
|
{
|
|
275
355
|
_fullSourcePath = GetFullPathFromRelative(_animationSourcePathRelative);
|
|
@@ -309,12 +389,7 @@
|
|
|
309
389
|
return !string.IsNullOrWhiteSpace(_animationSourcePathRelative)
|
|
310
390
|
&& !string.IsNullOrWhiteSpace(_animationDestinationPathRelative)
|
|
311
391
|
&& _fullSourcePath != null
|
|
312
|
-
&& _fullDestinationPath != null
|
|
313
|
-
&& !string.Equals(
|
|
314
|
-
_animationSourcePathRelative,
|
|
315
|
-
_animationDestinationPathRelative,
|
|
316
|
-
StringComparison.Ordinal
|
|
317
|
-
);
|
|
392
|
+
&& _fullDestinationPath != null;
|
|
318
393
|
}
|
|
319
394
|
|
|
320
395
|
private void AnalyzeAnimations()
|
|
@@ -361,10 +436,7 @@
|
|
|
361
436
|
string sourceRelPath = AssetDatabase.GUIDToAssetPath(guid);
|
|
362
437
|
if (
|
|
363
438
|
string.IsNullOrWhiteSpace(sourceRelPath)
|
|
364
|
-
|| !sourceRelPath.StartsWith(
|
|
365
|
-
_animationSourcePathRelative,
|
|
366
|
-
StringComparison.OrdinalIgnoreCase
|
|
367
|
-
)
|
|
439
|
+
|| !sourceRelPath.StartsWith(_animationSourcePathRelative)
|
|
368
440
|
)
|
|
369
441
|
{
|
|
370
442
|
continue;
|
|
@@ -388,7 +460,7 @@
|
|
|
388
460
|
FileName = Path.GetFileName(sourceRelPath),
|
|
389
461
|
RelativeDirectory = GetRelativeSubPath(
|
|
390
462
|
_animationSourcePathRelative,
|
|
391
|
-
directoryName.
|
|
463
|
+
directoryName.Replace(Path.DirectorySeparatorChar, '/')
|
|
392
464
|
),
|
|
393
465
|
Hash = CalculateFileHash(sourceFullPath),
|
|
394
466
|
};
|
|
@@ -397,7 +469,7 @@
|
|
|
397
469
|
fileInfo.RelativeDirectory,
|
|
398
470
|
fileInfo.FileName
|
|
399
471
|
)
|
|
400
|
-
.
|
|
472
|
+
.Replace(Path.DirectorySeparatorChar, '/');
|
|
401
473
|
_sourceAnimations.Add(fileInfo);
|
|
402
474
|
|
|
403
475
|
EditorUtility.DisplayProgressBar(
|
|
@@ -433,10 +505,7 @@
|
|
|
433
505
|
else
|
|
434
506
|
{
|
|
435
507
|
string destHash = CalculateFileHash(destFullPath);
|
|
436
|
-
if (
|
|
437
|
-
string.IsNullOrWhiteSpace(sourceInfo.Hash)
|
|
438
|
-
|| string.IsNullOrWhiteSpace(destHash)
|
|
439
|
-
)
|
|
508
|
+
if (string.IsNullOrEmpty(sourceInfo.Hash) || string.IsNullOrEmpty(destHash))
|
|
440
509
|
{
|
|
441
510
|
this.LogWarn(
|
|
442
511
|
$"Could not compare '{sourceInfo.FileName}' due to hashing error. Treating as 'Changed'."
|
|
@@ -524,32 +593,8 @@
|
|
|
524
593
|
|
|
525
594
|
int successCount = 0;
|
|
526
595
|
int errorCount = 0;
|
|
527
|
-
foreach (AnimationFileInfo animInfo in animationsToCopy)
|
|
528
|
-
{
|
|
529
|
-
string destinationAssetPath = animInfo.DestinationRelativePath;
|
|
530
|
-
string destDirectory = Path.GetDirectoryName(destinationAssetPath).SanitizePath();
|
|
531
|
-
|
|
532
|
-
if (
|
|
533
|
-
string.IsNullOrWhiteSpace(destDirectory)
|
|
534
|
-
|| AssetDatabase.IsValidFolder(destDirectory)
|
|
535
|
-
)
|
|
536
|
-
{
|
|
537
|
-
continue;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
try
|
|
541
|
-
{
|
|
542
|
-
DirectoryHelper.EnsureDirectoryExists(destDirectory);
|
|
543
|
-
}
|
|
544
|
-
catch (Exception ex)
|
|
545
|
-
{
|
|
546
|
-
this.LogError(
|
|
547
|
-
$"Failed to create destination directory '{destDirectory}' for animation '{animInfo.FileName}'. Error: {ex.Message}. Skipping."
|
|
548
|
-
);
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
596
|
AssetDatabase.StartAssetEditing();
|
|
597
|
+
|
|
553
598
|
try
|
|
554
599
|
{
|
|
555
600
|
for (int i = 0; i < animationsToCopy.Count; i++)
|
|
@@ -570,6 +615,27 @@
|
|
|
570
615
|
|
|
571
616
|
string sourceAssetPath = animInfo.RelativePath;
|
|
572
617
|
string destinationAssetPath = animInfo.DestinationRelativePath;
|
|
618
|
+
string destDirectory = Path.GetDirectoryName(destinationAssetPath);
|
|
619
|
+
|
|
620
|
+
if (
|
|
621
|
+
!string.IsNullOrEmpty(destDirectory)
|
|
622
|
+
&& !AssetDatabase.IsValidFolder(destDirectory)
|
|
623
|
+
)
|
|
624
|
+
{
|
|
625
|
+
try
|
|
626
|
+
{
|
|
627
|
+
EnsureDirectoryExists(destDirectory);
|
|
628
|
+
}
|
|
629
|
+
catch (Exception ex)
|
|
630
|
+
{
|
|
631
|
+
this.LogError(
|
|
632
|
+
$"Failed to create destination directory '{destDirectory}' for animation '{animInfo.FileName}'. Error: {ex.Message}. Skipping."
|
|
633
|
+
);
|
|
634
|
+
errorCount++;
|
|
635
|
+
continue;
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
|
|
573
639
|
bool copySuccessful = AssetDatabase.CopyAsset(
|
|
574
640
|
sourceAssetPath,
|
|
575
641
|
destinationAssetPath
|
|
@@ -718,7 +784,7 @@
|
|
|
718
784
|
return null;
|
|
719
785
|
}
|
|
720
786
|
|
|
721
|
-
fullPath = fullPath.
|
|
787
|
+
fullPath = fullPath.Replace(Path.DirectorySeparatorChar, '/');
|
|
722
788
|
if (
|
|
723
789
|
fullPath.EndsWith("/Assets", StringComparison.OrdinalIgnoreCase)
|
|
724
790
|
&& Path.GetFileName(fullPath).Equals("Assets", StringComparison.OrdinalIgnoreCase)
|
|
@@ -727,7 +793,7 @@
|
|
|
727
793
|
return "Assets";
|
|
728
794
|
}
|
|
729
795
|
|
|
730
|
-
string assetsPath = Application.dataPath.
|
|
796
|
+
string assetsPath = Application.dataPath.Replace(Path.DirectorySeparatorChar, '/');
|
|
731
797
|
if (fullPath.StartsWith(assetsPath, StringComparison.OrdinalIgnoreCase))
|
|
732
798
|
{
|
|
733
799
|
if (fullPath.Length == assetsPath.Length)
|
|
@@ -762,7 +828,7 @@
|
|
|
762
828
|
|
|
763
829
|
if (relativePath.Equals("Assets", StringComparison.OrdinalIgnoreCase))
|
|
764
830
|
{
|
|
765
|
-
return Application.dataPath.
|
|
831
|
+
return Application.dataPath.Replace(Path.DirectorySeparatorChar, '/');
|
|
766
832
|
}
|
|
767
833
|
|
|
768
834
|
if (relativePath.StartsWith("Assets/", StringComparison.OrdinalIgnoreCase))
|
|
@@ -771,7 +837,7 @@
|
|
|
771
837
|
0,
|
|
772
838
|
Application.dataPath.Length - "Assets".Length
|
|
773
839
|
);
|
|
774
|
-
return (projectRoot + relativePath).
|
|
840
|
+
return (projectRoot + relativePath).Replace(Path.DirectorySeparatorChar, '/');
|
|
775
841
|
}
|
|
776
842
|
return null;
|
|
777
843
|
}
|
|
@@ -800,32 +866,91 @@
|
|
|
800
866
|
return string.Empty;
|
|
801
867
|
}
|
|
802
868
|
|
|
803
|
-
private string CalculateFileHash(string filePath)
|
|
869
|
+
private static string CalculateFileHash(string filePath)
|
|
804
870
|
{
|
|
805
871
|
try
|
|
806
872
|
{
|
|
807
|
-
using MD5 md5 = MD5.Create()
|
|
808
|
-
using FileStream stream = File.OpenRead(filePath)
|
|
809
|
-
|
|
810
|
-
|
|
873
|
+
using (MD5 md5 = MD5.Create())
|
|
874
|
+
using (FileStream stream = File.OpenRead(filePath))
|
|
875
|
+
{
|
|
876
|
+
byte[] hashBytes = md5.ComputeHash(stream);
|
|
877
|
+
return BitConverter.ToString(hashBytes).Replace("-", "").ToLowerInvariant();
|
|
878
|
+
}
|
|
811
879
|
}
|
|
812
880
|
catch (IOException ioEx)
|
|
813
881
|
{
|
|
814
|
-
|
|
815
|
-
$"[AnimationCopierWindow] IO Error calculating hash for {filePath}."
|
|
816
|
-
ioEx
|
|
882
|
+
Debug.LogError(
|
|
883
|
+
$"[AnimationCopierWindow] IO Error calculating hash for {filePath}: {ioEx.Message}"
|
|
817
884
|
);
|
|
818
885
|
return string.Empty;
|
|
819
886
|
}
|
|
820
887
|
catch (Exception ex)
|
|
821
888
|
{
|
|
822
|
-
|
|
823
|
-
$"[AnimationCopierWindow] Error calculating hash for {filePath}."
|
|
824
|
-
ex
|
|
889
|
+
Debug.LogError(
|
|
890
|
+
$"[AnimationCopierWindow] Error calculating hash for {filePath}: {ex.Message}"
|
|
825
891
|
);
|
|
826
892
|
return string.Empty;
|
|
827
893
|
}
|
|
828
894
|
}
|
|
895
|
+
|
|
896
|
+
private void EnsureDirectoryExists(string relativeDirectoryPath)
|
|
897
|
+
{
|
|
898
|
+
if (string.IsNullOrWhiteSpace(relativeDirectoryPath))
|
|
899
|
+
{
|
|
900
|
+
return;
|
|
901
|
+
}
|
|
902
|
+
if (!relativeDirectoryPath.StartsWith("Assets/"))
|
|
903
|
+
{
|
|
904
|
+
if (relativeDirectoryPath.Equals("Assets", StringComparison.OrdinalIgnoreCase))
|
|
905
|
+
{
|
|
906
|
+
return;
|
|
907
|
+
}
|
|
908
|
+
|
|
909
|
+
this.LogError(
|
|
910
|
+
$"Attempted to create directory outside of Assets: '{relativeDirectoryPath}'"
|
|
911
|
+
);
|
|
912
|
+
throw new ArgumentException(
|
|
913
|
+
"Cannot create directories outside the Assets folder using AssetDatabase.",
|
|
914
|
+
nameof(relativeDirectoryPath)
|
|
915
|
+
);
|
|
916
|
+
}
|
|
917
|
+
|
|
918
|
+
if (AssetDatabase.IsValidFolder(relativeDirectoryPath))
|
|
919
|
+
{
|
|
920
|
+
return;
|
|
921
|
+
}
|
|
922
|
+
|
|
923
|
+
string parentPath = Path.GetDirectoryName(relativeDirectoryPath)
|
|
924
|
+
?.Replace(Path.DirectorySeparatorChar, '/');
|
|
925
|
+
|
|
926
|
+
if (
|
|
927
|
+
string.IsNullOrEmpty(parentPath)
|
|
928
|
+
|| parentPath.Equals("Assets", StringComparison.OrdinalIgnoreCase)
|
|
929
|
+
)
|
|
930
|
+
{
|
|
931
|
+
string folderNameToCreate = Path.GetFileName(relativeDirectoryPath);
|
|
932
|
+
if (
|
|
933
|
+
!string.IsNullOrEmpty(folderNameToCreate)
|
|
934
|
+
&& !AssetDatabase.IsValidFolder(relativeDirectoryPath)
|
|
935
|
+
)
|
|
936
|
+
{
|
|
937
|
+
AssetDatabase.CreateFolder("Assets", folderNameToCreate);
|
|
938
|
+
}
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
EnsureDirectoryExists(parentPath);
|
|
943
|
+
|
|
944
|
+
string currentFolderName = Path.GetFileName(relativeDirectoryPath);
|
|
945
|
+
if (
|
|
946
|
+
!string.IsNullOrEmpty(currentFolderName)
|
|
947
|
+
&& !AssetDatabase.IsValidFolder(relativeDirectoryPath)
|
|
948
|
+
)
|
|
949
|
+
{
|
|
950
|
+
AssetDatabase.CreateFolder(parentPath, currentFolderName);
|
|
951
|
+
this.Log($"Created folder: {relativeDirectoryPath}");
|
|
952
|
+
}
|
|
953
|
+
}
|
|
829
954
|
}
|
|
830
955
|
#endif
|
|
831
956
|
}
|