Last active
May 22, 2024 02:43
-
-
Save SolarianZ/405ffa7acdce2138e3b4517eefdea342 to your computer and use it in GitHub Desktop.
{"category": "Unity Engine/Editor/Extensions", "keywords": "Unity, Editor, Asset, Move"} Add 'Move to' menu item to move selected assets to a folder.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Collections.Generic; | |
using System.Linq; | |
using UnityEditor; | |
using UnityEngine; | |
public static class AssetTool | |
{ | |
// Add 'Move to' menu item to move selected assets to a folder | |
[MenuItem("Tools/Bamboo/Asset/Move Selected Assets to Folder")] | |
[MenuItem("Assets/Move to", priority = 20)] | |
public static void MoveSelectedAssetsToFolder() | |
{ | |
// Filter root assets | |
// `Selection.objects` contains `null` when selecting a Scene in the Hierarchy window | |
IEnumerable<UnityEngine.Object> assets = Selection.objects | |
.Where(obj => obj && !AssetDatabase.IsSubAsset(obj) && EditorUtility.IsPersistent(obj)); | |
string targetFolderPath = EditorUtility.OpenFolderPanel("Select Folder", "Assets", ""); | |
if (string.IsNullOrEmpty(targetFolderPath)) | |
{ | |
return; | |
} | |
if (!targetFolderPath.StartsWith(Application.dataPath)) | |
{ | |
Debug.LogError("Can not move assets to outside of the project folder."); | |
return; | |
} | |
try | |
{ | |
AssetDatabase.StartAssetEditing(); | |
bool noAssetsSelected = true; | |
foreach (Object asset in assets) | |
{ | |
noAssetsSelected = false; | |
string folderRelativePath = targetFolderPath.Replace(Application.dataPath, "Assets"); | |
string assetPath = AssetDatabase.GetAssetPath(asset); | |
string assetExt = System.IO.Path.GetExtension(assetPath); | |
string newAssetPath = $"{folderRelativePath}/{asset.name}{assetExt}"; | |
if (assetPath.Equals(newAssetPath)) | |
{ | |
continue; | |
} | |
Object assetAtNewPath = AssetDatabase.LoadAssetAtPath<Object>(newAssetPath); | |
if (assetAtNewPath) | |
{ | |
int operation = EditorUtility.DisplayDialogComplex("Alert", | |
$"Asset '{asset.name}' already exists at '{targetFolderPath}', please select an operation:\n" + | |
$"- Replace: Replace the existing asset with the selected asset, the reference to the existing asset will be lost.\n" + | |
$"- Generate suffix: Generate a unique suffix for the selected asset and move it to the folder.\n" + | |
$"- Cancel move: Cancel the move operation.", | |
"Replace", "Cancel move", "Generate suffix"); | |
switch (operation) | |
{ | |
case 0: // Overwrite | |
AssetDatabase.DeleteAsset(newAssetPath); | |
break; | |
case 1: // Cancel move | |
continue; | |
case 2: // Generate suffix | |
newAssetPath = AssetDatabase.GenerateUniqueAssetPath(newAssetPath); | |
break; | |
} | |
} | |
AssetDatabase.MoveAsset(assetPath, newAssetPath); | |
UnityEngine.Debug.Log($"Move asset: {assetPath} -> {newAssetPath}", asset); | |
EditorGUIUtility.PingObject(asset); | |
} | |
if (noAssetsSelected) | |
{ | |
Debug.LogError("No root asset selected for move."); | |
return; | |
} | |
} | |
finally | |
{ | |
AssetDatabase.StopAssetEditing(); | |
} | |
} | |
[MenuItem("Tools/Bamboo/Asset/Move Selected Assets to Folder", validate = true)] | |
[MenuItem("Assets/Move to", priority = 20, validate = true)] | |
public static bool HasMovableAssetsSelected() | |
{ | |
return Selection.objects | |
.Any(obj => obj && !AssetDatabase.IsSubAsset(obj) && EditorUtility.IsPersistent(obj)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment