234 lines
7.1 KiB
C#
234 lines
7.1 KiB
C#
using UnityEditor;
|
|
using UnityEditor.SceneManagement;
|
|
using UnityEngine;
|
|
using UnityEngine.SceneManagement;
|
|
|
|
namespace BrewMonster.Scripts.Utils.Editor
|
|
{
|
|
public static class ClearMissingScript
|
|
{
|
|
[MenuItem("Tools/Brew Monster/Clear Missing Script/Active Scene")]
|
|
public static void ClearMissingScriptsInActiveScene()
|
|
{
|
|
var scene = SceneManager.GetActiveScene();
|
|
if (!scene.IsValid())
|
|
{
|
|
EditorUtility.DisplayDialog("Clear Missing Script", "No valid active scene.", "OK");
|
|
return;
|
|
}
|
|
|
|
int removedCount = 0;
|
|
var roots = scene.GetRootGameObjects();
|
|
foreach (var root in roots)
|
|
{
|
|
Undo.RegisterFullObjectHierarchyUndo(root, "Clear Missing Scripts");
|
|
removedCount += RemoveMissingScriptsRecursive(root);
|
|
}
|
|
|
|
if (removedCount > 0)
|
|
{
|
|
EditorSceneManager.MarkSceneDirty(scene);
|
|
}
|
|
|
|
EditorUtility.DisplayDialog("Clear Missing Script", $"Removed {removedCount} missing script(s) from active scene.", "OK");
|
|
}
|
|
|
|
[MenuItem("Tools/Brew Monster/Clear Missing Script/Prefabs in Selected Folder", true)]
|
|
public static bool ValidateClearMissingScriptsInSelectedFolder()
|
|
{
|
|
Object selectedObject = Selection.activeObject;
|
|
if (selectedObject == null)
|
|
return false;
|
|
|
|
string folderPath = AssetDatabase.GetAssetPath(selectedObject);
|
|
return AssetDatabase.IsValidFolder(folderPath);
|
|
}
|
|
|
|
[MenuItem("Tools/Brew Monster/Clear Missing Script/Prefabs in Selected Folder")]
|
|
public static void ClearMissingScriptsInSelectedFolder()
|
|
{
|
|
Object selectedObject = Selection.activeObject;
|
|
if (selectedObject == null)
|
|
{
|
|
EditorUtility.DisplayDialog("Clear Missing Script",
|
|
"Please select a folder in the Project window first.", "OK");
|
|
return;
|
|
}
|
|
|
|
string folderPath = AssetDatabase.GetAssetPath(selectedObject);
|
|
if (!AssetDatabase.IsValidFolder(folderPath))
|
|
{
|
|
EditorUtility.DisplayDialog("Clear Missing Script",
|
|
"Selected object is not a valid folder. Please select a folder in the Project window.", "OK");
|
|
return;
|
|
}
|
|
|
|
if (!EditorUtility.DisplayDialog("Clear Missing Script in Folder",
|
|
$"This will process all prefabs in:\n{folderPath}\n\nContinue?",
|
|
"Yes", "Cancel"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ProcessPrefabsInFolder(folderPath);
|
|
}
|
|
|
|
[MenuItem("Tools/Brew Monster/Clear Missing Script/All Prefabs")]
|
|
public static void ClearMissingScriptsInPrefabs()
|
|
{
|
|
if (!EditorUtility.DisplayDialog("Clear Missing Script in Prefabs",
|
|
"This will process all prefabs in the project. This may take a while. Continue?",
|
|
"Yes", "Cancel"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
ProcessPrefabsInFolder("Assets");
|
|
}
|
|
|
|
private static void ProcessPrefabsInFolder(string folderPath)
|
|
{
|
|
string[] prefabGUIDs = AssetDatabase.FindAssets("t:Prefab", new[] { folderPath });
|
|
int totalPrefabs = prefabGUIDs.Length;
|
|
|
|
if (totalPrefabs == 0)
|
|
{
|
|
EditorUtility.DisplayDialog("Clear Missing Script",
|
|
$"No prefabs found in folder:\n{folderPath}", "OK");
|
|
return;
|
|
}
|
|
|
|
int processedCount = 0;
|
|
int totalRemovedCount = 0;
|
|
int prefabsWithRemovals = 0;
|
|
|
|
EditorUtility.DisplayProgressBar("Clear Missing Scripts", "Processing prefabs...", 0f);
|
|
|
|
try
|
|
{
|
|
foreach (string guid in prefabGUIDs)
|
|
{
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
|
processedCount++;
|
|
|
|
EditorUtility.DisplayProgressBar("Clear Missing Scripts",
|
|
$"Processing: {assetPath} ({processedCount}/{totalPrefabs})",
|
|
(float)processedCount / totalPrefabs);
|
|
|
|
GameObject prefabRoot = PrefabUtility.LoadPrefabContents(assetPath);
|
|
if (prefabRoot != null)
|
|
{
|
|
int removedCount = RemoveMissingScriptsRecursive(prefabRoot);
|
|
|
|
if (removedCount > 0)
|
|
{
|
|
PrefabUtility.SaveAsPrefabAsset(prefabRoot, assetPath);
|
|
totalRemovedCount += removedCount;
|
|
prefabsWithRemovals++;
|
|
Debug.Log($"[ClearMissingScript] Removed {removedCount} missing script(s) from prefab: {assetPath}");
|
|
}
|
|
|
|
PrefabUtility.UnloadPrefabContents(prefabRoot);
|
|
}
|
|
}
|
|
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
finally
|
|
{
|
|
EditorUtility.ClearProgressBar();
|
|
}
|
|
|
|
EditorUtility.DisplayDialog("Clear Missing Script",
|
|
$"Processed {processedCount} prefab(s) in folder:\n{folderPath}\n\nRemoved {totalRemovedCount} missing script(s) from {prefabsWithRemovals} prefab(s).",
|
|
"OK");
|
|
}
|
|
|
|
[MenuItem("Tools/Brew Monster/Clear Missing Script/Scene and Prefabs")]
|
|
public static void ClearMissingScriptsInSceneAndPrefabs()
|
|
{
|
|
if (!EditorUtility.DisplayDialog("Clear Missing Script",
|
|
"This will process the active scene and all prefabs in the project. This may take a while. Continue?",
|
|
"Yes", "Cancel"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
int sceneRemovedCount = 0;
|
|
var scene = SceneManager.GetActiveScene();
|
|
if (scene.IsValid())
|
|
{
|
|
var roots = scene.GetRootGameObjects();
|
|
foreach (var root in roots)
|
|
{
|
|
Undo.RegisterFullObjectHierarchyUndo(root, "Clear Missing Scripts");
|
|
sceneRemovedCount += RemoveMissingScriptsRecursive(root);
|
|
}
|
|
|
|
if (sceneRemovedCount > 0)
|
|
{
|
|
EditorSceneManager.MarkSceneDirty(scene);
|
|
}
|
|
}
|
|
|
|
string[] prefabGUIDs = AssetDatabase.FindAssets("t:Prefab");
|
|
int totalPrefabs = prefabGUIDs.Length;
|
|
int processedCount = 0;
|
|
int prefabRemovedCount = 0;
|
|
int prefabsWithRemovals = 0;
|
|
|
|
EditorUtility.DisplayProgressBar("Clear Missing Scripts", "Processing prefabs...", 0f);
|
|
|
|
try
|
|
{
|
|
foreach (string guid in prefabGUIDs)
|
|
{
|
|
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
|
processedCount++;
|
|
|
|
EditorUtility.DisplayProgressBar("Clear Missing Scripts",
|
|
$"Processing: {assetPath} ({processedCount}/{totalPrefabs})",
|
|
(float)processedCount / totalPrefabs);
|
|
|
|
GameObject prefabRoot = PrefabUtility.LoadPrefabContents(assetPath);
|
|
if (prefabRoot != null)
|
|
{
|
|
int removedCount = RemoveMissingScriptsRecursive(prefabRoot);
|
|
|
|
if (removedCount > 0)
|
|
{
|
|
PrefabUtility.SaveAsPrefabAsset(prefabRoot, assetPath);
|
|
prefabRemovedCount += removedCount;
|
|
prefabsWithRemovals++;
|
|
}
|
|
|
|
PrefabUtility.UnloadPrefabContents(prefabRoot);
|
|
}
|
|
}
|
|
|
|
AssetDatabase.SaveAssets();
|
|
}
|
|
finally
|
|
{
|
|
EditorUtility.ClearProgressBar();
|
|
}
|
|
|
|
int totalRemoved = sceneRemovedCount + prefabRemovedCount;
|
|
EditorUtility.DisplayDialog("Clear Missing Script",
|
|
$"Scene: Removed {sceneRemovedCount} missing script(s).\n" +
|
|
$"Prefabs: Processed {processedCount} prefab(s), removed {prefabRemovedCount} missing script(s) from {prefabsWithRemovals} prefab(s).\n" +
|
|
$"Total: {totalRemoved} missing script(s) removed.",
|
|
"OK");
|
|
}
|
|
|
|
private static int RemoveMissingScriptsRecursive(GameObject gameObject)
|
|
{
|
|
int removed = GameObjectUtility.RemoveMonoBehavioursWithMissingScript(gameObject);
|
|
for (int i = 0; i < gameObject.transform.childCount; i++)
|
|
{
|
|
removed += RemoveMissingScriptsRecursive(gameObject.transform.GetChild(i).gameObject);
|
|
}
|
|
return removed;
|
|
}
|
|
}
|
|
} |