295 lines
10 KiB
C#
295 lines
10 KiB
C#
using UnityEngine;
|
|
using UnityEditor;
|
|
using System.IO;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
public class PrefabMoverTool : EditorWindow
|
|
{
|
|
private Object folderRoot;
|
|
private string folderRootPath = "";
|
|
private string subfolderPath = "";
|
|
private Object prefabToMove;
|
|
|
|
private Vector2 scrollPosition;
|
|
private GUIStyle headerStyle;
|
|
private GUIStyle boxStyle;
|
|
|
|
[MenuItem("Tools/Prefab Mover")]
|
|
public static void ShowWindow()
|
|
{
|
|
PrefabMoverTool window = GetWindow<PrefabMoverTool>("Prefab Mover");
|
|
window.minSize = new Vector2(400, 300);
|
|
window.Show();
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
// Initialize styles
|
|
InitializeStyles();
|
|
}
|
|
|
|
private void InitializeStyles()
|
|
{
|
|
if (headerStyle == null)
|
|
{
|
|
headerStyle = new GUIStyle(EditorStyles.boldLabel)
|
|
{
|
|
fontSize = 14,
|
|
alignment = TextAnchor.MiddleLeft,
|
|
margin = new RectOffset(5, 5, 10, 10)
|
|
};
|
|
}
|
|
|
|
if (boxStyle == null)
|
|
{
|
|
boxStyle = new GUIStyle(GUI.skin.box)
|
|
{
|
|
padding = new RectOffset(10, 10, 10, 10),
|
|
margin = new RectOffset(5, 5, 5, 5)
|
|
};
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
InitializeStyles();
|
|
|
|
scrollPosition = EditorGUILayout.BeginScrollView(scrollPosition);
|
|
|
|
// Title
|
|
GUILayout.Label("Prefab Mover Tool", headerStyle);
|
|
EditorGUILayout.Space(5);
|
|
|
|
// Folder Root Section
|
|
EditorGUILayout.BeginVertical(boxStyle);
|
|
{
|
|
GUILayout.Label("1. Set Folder Root", EditorStyles.boldLabel);
|
|
EditorGUILayout.HelpBox("Drag and drop a folder from the Project window to set the root folder.", MessageType.Info);
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.Label("Folder Root:", GUILayout.Width(100));
|
|
|
|
Object newFolderRoot = EditorGUILayout.ObjectField(folderRoot, typeof(Object), false);
|
|
if (newFolderRoot != folderRoot)
|
|
{
|
|
folderRoot = newFolderRoot;
|
|
UpdateFolderRootPath();
|
|
}
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
if (!string.IsNullOrEmpty(folderRootPath))
|
|
{
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.Label("Path:", GUILayout.Width(100));
|
|
EditorGUILayout.SelectableLabel(folderRootPath, EditorStyles.textField, GUILayout.Height(18));
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
|
|
EditorGUILayout.Space(5);
|
|
|
|
// Subfolder Path Section
|
|
EditorGUILayout.BeginVertical(boxStyle);
|
|
{
|
|
GUILayout.Label("2. Set Subfolder Path", EditorStyles.boldLabel);
|
|
EditorGUILayout.HelpBox("Enter the subfolder path (e.g., 'a/b' or 'a\\b'). This will be created inside the folder root.", MessageType.Info);
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.Label("Subfolder Path:", GUILayout.Width(100));
|
|
subfolderPath = EditorGUILayout.TextField(subfolderPath);
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
if (!string.IsNullOrEmpty(folderRootPath) && !string.IsNullOrEmpty(subfolderPath))
|
|
{
|
|
string fullPath = GetFullTargetPath();
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.Label("Full Path:", GUILayout.Width(100));
|
|
EditorGUILayout.SelectableLabel(fullPath, EditorStyles.textField, GUILayout.Height(18));
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
|
|
EditorGUILayout.Space(5);
|
|
|
|
// Prefab Section
|
|
EditorGUILayout.BeginVertical(boxStyle);
|
|
{
|
|
GUILayout.Label("3. Select Prefab to Move", EditorStyles.boldLabel);
|
|
EditorGUILayout.HelpBox("Drag and drop a prefab from the Project window.", MessageType.Info);
|
|
|
|
EditorGUILayout.BeginHorizontal();
|
|
GUILayout.Label("Prefab:", GUILayout.Width(100));
|
|
prefabToMove = EditorGUILayout.ObjectField(prefabToMove, typeof(GameObject), false);
|
|
EditorGUILayout.EndHorizontal();
|
|
}
|
|
EditorGUILayout.EndVertical();
|
|
|
|
EditorGUILayout.Space(10);
|
|
|
|
// Move Button
|
|
EditorGUI.BeginDisabledGroup(!CanMovePrefab());
|
|
{
|
|
if (GUILayout.Button("Move Prefab", GUILayout.Height(35)))
|
|
{
|
|
MovePrefab();
|
|
}
|
|
}
|
|
EditorGUI.EndDisabledGroup();
|
|
|
|
if (!CanMovePrefab())
|
|
{
|
|
if (string.IsNullOrEmpty(folderRootPath))
|
|
EditorGUILayout.HelpBox("Please set a folder root.", MessageType.Warning);
|
|
else if (string.IsNullOrEmpty(subfolderPath))
|
|
EditorGUILayout.HelpBox("Please enter a subfolder path.", MessageType.Warning);
|
|
else if (prefabToMove == null)
|
|
EditorGUILayout.HelpBox("Please select a prefab to move.", MessageType.Warning);
|
|
}
|
|
|
|
EditorGUILayout.EndScrollView();
|
|
}
|
|
|
|
private void UpdateFolderRootPath()
|
|
{
|
|
if (folderRoot == null)
|
|
{
|
|
folderRootPath = "";
|
|
return;
|
|
}
|
|
|
|
string path = AssetDatabase.GetAssetPath(folderRoot);
|
|
|
|
// Check if it's a folder
|
|
if (Directory.Exists(path))
|
|
{
|
|
folderRootPath = path;
|
|
}
|
|
else if (File.Exists(path))
|
|
{
|
|
// If user dropped a file, use its parent folder
|
|
folderRootPath = Path.GetDirectoryName(path);
|
|
EditorUtility.DisplayDialog("Info", "You selected a file. Using its parent folder instead.", "OK");
|
|
}
|
|
else
|
|
{
|
|
folderRootPath = "";
|
|
EditorUtility.DisplayDialog("Error", "Invalid folder selected.", "OK");
|
|
}
|
|
}
|
|
|
|
private string GetFullTargetPath()
|
|
{
|
|
if (string.IsNullOrEmpty(folderRootPath) || string.IsNullOrEmpty(subfolderPath))
|
|
return "";
|
|
|
|
// Normalize the subfolder path (replace backslashes with forward slashes)
|
|
string normalizedSubPath = subfolderPath.Replace('\\', '/');
|
|
|
|
// Combine paths
|
|
string fullPath = Path.Combine(folderRootPath, normalizedSubPath);
|
|
|
|
// Normalize to forward slashes (Unity convention)
|
|
return fullPath.Replace('\\', '/');
|
|
}
|
|
|
|
private bool CanMovePrefab()
|
|
{
|
|
return !string.IsNullOrEmpty(folderRootPath) &&
|
|
!string.IsNullOrEmpty(subfolderPath) &&
|
|
prefabToMove != null;
|
|
}
|
|
|
|
private void MovePrefab()
|
|
{
|
|
string prefabPath = AssetDatabase.GetAssetPath(prefabToMove);
|
|
|
|
if (string.IsNullOrEmpty(prefabPath))
|
|
{
|
|
EditorUtility.DisplayDialog("Error", "Cannot get prefab path.", "OK");
|
|
return;
|
|
}
|
|
|
|
// Get the full target path
|
|
string targetFolder = GetFullTargetPath();
|
|
|
|
// Create the folder structure if it doesn't exist
|
|
CreateFolderStructure(targetFolder);
|
|
|
|
// Get prefab filename
|
|
string prefabFileName = Path.GetFileName(prefabPath);
|
|
string targetPath = Path.Combine(targetFolder, prefabFileName).Replace('\\', '/');
|
|
|
|
// Check if file already exists at target
|
|
if (File.Exists(targetPath))
|
|
{
|
|
bool overwrite = EditorUtility.DisplayDialog(
|
|
"File Exists",
|
|
$"A file with the name '{prefabFileName}' already exists at:\n{targetPath}\n\nDo you want to overwrite it?",
|
|
"Overwrite",
|
|
"Cancel"
|
|
);
|
|
|
|
if (!overwrite)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
// Move the asset
|
|
string error = AssetDatabase.MoveAsset(prefabPath, targetPath);
|
|
|
|
if (string.IsNullOrEmpty(error))
|
|
{
|
|
AssetDatabase.Refresh();
|
|
EditorUtility.DisplayDialog("Success", $"Prefab moved successfully to:\n{targetPath}", "OK");
|
|
|
|
// Clear the prefab field after successful move
|
|
prefabToMove = null;
|
|
|
|
// Ping the moved asset in the Project window
|
|
Object movedAsset = AssetDatabase.LoadAssetAtPath<Object>(targetPath);
|
|
EditorGUIUtility.PingObject(movedAsset);
|
|
}
|
|
else
|
|
{
|
|
EditorUtility.DisplayDialog("Error", $"Failed to move prefab:\n{error}", "OK");
|
|
}
|
|
}
|
|
|
|
private void CreateFolderStructure(string fullPath)
|
|
{
|
|
// Normalize path
|
|
fullPath = fullPath.Replace('\\', '/');
|
|
|
|
// Split the path into parts
|
|
string[] pathParts = fullPath.Split('/');
|
|
string currentPath = "";
|
|
|
|
foreach (string part in pathParts)
|
|
{
|
|
if (string.IsNullOrEmpty(part))
|
|
continue;
|
|
|
|
string parentPath = currentPath;
|
|
currentPath = string.IsNullOrEmpty(currentPath) ? part : currentPath + "/" + part;
|
|
|
|
// Check if folder exists
|
|
if (!Directory.Exists(currentPath))
|
|
{
|
|
// Create the folder using AssetDatabase
|
|
if (!string.IsNullOrEmpty(parentPath))
|
|
{
|
|
AssetDatabase.CreateFolder(parentPath, part);
|
|
Debug.Log($"Created folder: {currentPath}");
|
|
}
|
|
}
|
|
}
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
}
|
|
}
|