diff --git a/AssetStudioGUI/AssetStudioGUIForm.cs b/AssetStudioGUI/AssetStudioGUIForm.cs index 4f52ae1..4f89887 100644 --- a/AssetStudioGUI/AssetStudioGUIForm.cs +++ b/AssetStudioGUI/AssetStudioGUIForm.cs @@ -89,6 +89,10 @@ namespace AssetStudioGUI private AlphanumComparatorFast alphanumComparator = new AlphanumComparatorFast(); #endif + //asset list selection + private List selectedIndicesPrevList = new List(); + private List selectedAnimationAssetsList = new List(); + //asset list filter private System.Timers.Timer delayTimer; private bool enableFiltering; @@ -695,6 +699,8 @@ namespace AssetStudioGUI sortColumn = e.Column; assetListView.BeginUpdate(); assetListView.SelectedIndices.Clear(); + selectedIndicesPrevList.Clear(); + selectedAnimationAssetsList.Clear(); if (sortColumn == 4) //FullSize { visibleAssets.Sort((a, b) => @@ -1366,6 +1372,8 @@ namespace AssetStudioGUI assetListView.Items.Clear(); classesListView.Items.Clear(); classesListView.Groups.Clear(); + selectedAnimationAssetsList.Clear(); + selectedIndicesPrevList.Clear(); previewPanel.BackgroundImage = Properties.Resources.preview; imageTexture?.Dispose(); imageTexture = null; @@ -1459,7 +1467,6 @@ namespace AssetStudioGUI private void exportAnimatorwithAnimationClipMenuItem_Click(object sender, EventArgs e) { AssetItem animator = null; - List animationList = new List(); var selectedAssets = GetSelectedAssets(); foreach (var assetPreloadData in selectedAssets) { @@ -1467,10 +1474,6 @@ namespace AssetStudioGUI { animator = assetPreloadData; } - else if (assetPreloadData.Type == ClassIDType.AnimationClip) - { - animationList.Add(assetPreloadData); - } } if (animator != null) @@ -1481,7 +1484,7 @@ namespace AssetStudioGUI { saveDirectoryBackup = saveFolderDialog.Folder; var exportPath = Path.Combine(saveFolderDialog.Folder, "Animator") + Path.DirectorySeparatorChar; - ExportAnimatorWithAnimationClip(animator, animationList, exportPath); + ExportAnimatorWithAnimationClip(animator, selectedAnimationAssetsList, exportPath); } } } @@ -1661,14 +1664,44 @@ namespace AssetStudioGUI private void assetListView_SelectedIndexChanged(object sender, EventArgs e) { - if (assetListView.SelectedIndices.Count > 1) - StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets."); + ProcessSelectedItems(); } private void assetListView_VirtualItemsSelectionRangeChanged(object sender, ListViewVirtualItemsSelectionRangeChangedEventArgs e) + { + ProcessSelectedItems(); + } + + private void ProcessSelectedItems() { if (assetListView.SelectedIndices.Count > 1) + { StatusStripUpdate($"Selected {assetListView.SelectedIndices.Count} assets."); + } + + var selectedIndicesList = assetListView.SelectedIndices.Cast().ToList(); + + var addedIndices = selectedIndicesList.Except(selectedIndicesPrevList).ToArray(); + foreach (var itemIndex in addedIndices) + { + selectedIndicesPrevList.Add(itemIndex); + var selectedItem = (AssetItem)assetListView.Items[itemIndex]; + if (selectedItem.Type == ClassIDType.AnimationClip) + { + selectedAnimationAssetsList.Add(selectedItem); + } + } + + var removedIndices = selectedIndicesPrevList.Except(selectedIndicesList).ToArray(); + foreach (var itemIndex in removedIndices) + { + selectedIndicesPrevList.Remove(itemIndex); + var unselectedItem = (AssetItem)assetListView.Items[itemIndex]; + if (unselectedItem.Type == ClassIDType.AnimationClip) + { + selectedAnimationAssetsList.Remove(unselectedItem); + } + } } private List GetSelectedAssets() diff --git a/AssetStudioGUI/Studio.cs b/AssetStudioGUI/Studio.cs index bf98efa..27e70c8 100644 --- a/AssetStudioGUI/Studio.cs +++ b/AssetStudioGUI/Studio.cs @@ -626,6 +626,7 @@ namespace AssetStudioGUI { Progress.Reset(); Logger.Info($"Exporting {animator.Text}"); + Logger.Debug($"Selected AnimationClip(s):\n\"{string.Join("\"\n\"", animationList.Select(x => x.Text))}\""); try { ExportAnimator(animator, exportPath, animationList); diff --git a/AssetStudioUtility/ModelConverter.cs b/AssetStudioUtility/ModelConverter.cs index ca2bcdf..839b097 100644 --- a/AssetStudioUtility/ModelConverter.cs +++ b/AssetStudioUtility/ModelConverter.cs @@ -16,7 +16,7 @@ namespace AssetStudio private ImageFormat imageFormat; private Avatar avatar; - private HashSet animationClipHashSet = new HashSet(); + private AnimationClip[] animationClipUniqArray = Array.Empty(); private Dictionary boundAnimationPathDic = new Dictionary(); private Dictionary bonePathHash = new Dictionary(); private Dictionary textureNameDictionary = new Dictionary(); @@ -40,10 +40,7 @@ namespace AssetStudio } if (animationList != null) { - foreach (var animationClip in animationList) - { - animationClipHashSet.Add(animationClip); - } + animationClipUniqArray = animationList.Distinct().ToArray(); } ConvertAnimations(); } @@ -70,10 +67,7 @@ namespace AssetStudio } if (animationList != null) { - foreach (var animationClip in animationList) - { - animationClipHashSet.Add(animationClip); - } + animationClipUniqArray = animationList.Distinct().ToArray(); } ConvertAnimations(); } @@ -88,10 +82,7 @@ namespace AssetStudio } else { - foreach (var animationClip in animationList) - { - animationClipHashSet.Add(animationClip); - } + animationClipUniqArray = animationList.Distinct().ToArray(); } ConvertAnimations(); } @@ -160,6 +151,7 @@ namespace AssetStudio if (m_GameObject.m_Animation != null) { + var animationList = new List(); foreach (var animation in m_GameObject.m_Animation.m_Animations) { if (animation.TryGet(out var animationClip)) @@ -168,9 +160,10 @@ namespace AssetStudio { boundAnimationPathDic.Add(animationClip, GetTransformPath(m_Transform)); } - animationClipHashSet.Add(animationClip); + animationList.Add(animationClip); } } + animationClipUniqArray = animationList.Distinct().ToArray(); } foreach (var pptr in m_Transform.m_Children) @@ -184,6 +177,7 @@ namespace AssetStudio { if (m_Animator.m_Controller.TryGet(out var m_Controller)) { + var animationList = new List(); switch (m_Controller) { case AnimatorOverrideController m_AnimatorOverrideController: @@ -194,7 +188,7 @@ namespace AssetStudio { if (pptr.TryGet(out var m_AnimationClip)) { - animationClipHashSet.Add(m_AnimationClip); + animationList.Add(m_AnimationClip); } } } @@ -207,12 +201,13 @@ namespace AssetStudio { if (pptr.TryGet(out var m_AnimationClip)) { - animationClipHashSet.Add(m_AnimationClip); + animationList.Add(m_AnimationClip); } } break; } } + animationClipUniqArray = animationList.Distinct().ToArray(); } } @@ -769,7 +764,7 @@ namespace AssetStudio private void ConvertAnimations() { - foreach (var animationClip in animationClipHashSet) + foreach (var animationClip in animationClipUniqArray) { var iAnim = new ImportedKeyframedAnimation(); var name = animationClip.m_Name;