You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
148 lines
5.0 KiB
148 lines
5.0 KiB
8 months ago
|
using System.Collections.Generic;
|
||
|
using UnityEngine;
|
||
|
using UnityEditor;
|
||
|
using System;
|
||
|
|
||
|
public class RemoveMissingScripts : EditorWindow
|
||
|
{
|
||
|
private static void RemoveMissingScriptsFromSelectedObjects()
|
||
|
{
|
||
|
List<GameObject> gameObjectsWithMissingScripts = new List<GameObject>();
|
||
|
foreach (GameObject go in Selection.gameObjects)
|
||
|
{
|
||
|
Component[] components = go.GetComponents<Component>();
|
||
|
foreach (Component component in components)
|
||
|
{
|
||
|
if (component == null)
|
||
|
{
|
||
|
gameObjectsWithMissingScripts.Add(go);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
foreach (GameObject go in gameObjectsWithMissingScripts)
|
||
|
{
|
||
|
Component[] components = go.GetComponents<Component>();
|
||
|
for (int i = 0; i < components.Length; i++)
|
||
|
{
|
||
|
if (components[i] == null)
|
||
|
{
|
||
|
DestroyImmediate(go.GetComponent(components[i].GetType()));
|
||
|
i--; // Component array has changed, so decrement index to check new component at same position
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
EditorUtility.DisplayDialog("Completed", "Removed missing scripts from selected objects.", "OK");
|
||
|
}
|
||
|
[MenuItem("Tools/Remove Missing Scripts from Scene")]
|
||
|
private static void RemoveMissingScriptsInScene()
|
||
|
{
|
||
|
GameObject[] allObjects = FindObjectsByType<GameObject>(FindObjectsSortMode.None);
|
||
|
int totalRemovedScripts = 0;
|
||
|
|
||
|
foreach (GameObject obj in allObjects)
|
||
|
{
|
||
|
int removedCount = RemovesMissingScripts(obj);
|
||
|
if (removedCount > 0)
|
||
|
{
|
||
|
totalRemovedScripts += removedCount;
|
||
|
Debug.Log($"Removed {removedCount} missing scripts from GameObject: {obj.name}");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Debug.Log($"Total removed missing scripts from scene: {totalRemovedScripts}");
|
||
|
}
|
||
|
|
||
|
private static int RemovesMissingScripts(GameObject obj)
|
||
|
{
|
||
|
int removedCount = 0;
|
||
|
Transform[] transforms = obj.GetComponentsInChildren<Transform>(true);
|
||
|
|
||
|
foreach (Transform t in transforms)
|
||
|
{
|
||
|
Component[] components = t.gameObject.GetComponents<Component>();
|
||
|
|
||
|
SerializedObject so = new SerializedObject(t.gameObject);
|
||
|
SerializedProperty prop = so.FindProperty("m_Component");
|
||
|
|
||
|
int nullCount = 0;
|
||
|
|
||
|
for (int i = 0; i < components.Length; i++)
|
||
|
{
|
||
|
if (components[i] == null)
|
||
|
{
|
||
|
prop.DeleteArrayElementAtIndex(i - nullCount);
|
||
|
nullCount++;
|
||
|
removedCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
so.ApplyModifiedProperties();
|
||
|
}
|
||
|
|
||
|
return removedCount;
|
||
|
}
|
||
|
[MenuItem("Tools/Remove Missing Scripts from Selected Prefabs")]
|
||
|
private static void RemoveMissingScriptsInSelectedPrefabs()
|
||
|
{
|
||
|
// 获取选中的所有对象
|
||
|
GameObject[] selectedObjects = Selection.gameObjects;
|
||
|
int totalRemovedScripts = 0;
|
||
|
|
||
|
foreach (GameObject selectedObject in selectedObjects)
|
||
|
{
|
||
|
string prefabPath = AssetDatabase.GetAssetPath(selectedObject);
|
||
|
if (string.IsNullOrEmpty(prefabPath) || PrefabUtility.GetPrefabAssetType(selectedObject) == PrefabAssetType.NotAPrefab)
|
||
|
{
|
||
|
Debug.LogWarning($"Selected object '{selectedObject.name}' is not a prefab.");
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
// 打开预设以编辑模式加载
|
||
|
GameObject prefabInstance = PrefabUtility.LoadPrefabContents(prefabPath);
|
||
|
int removedCount = RemoveAllMissingScripts(prefabInstance);
|
||
|
|
||
|
if (removedCount > 0)
|
||
|
{
|
||
|
totalRemovedScripts += removedCount;
|
||
|
Debug.Log($"Removed {removedCount} missing scripts from prefab: {prefabPath}");
|
||
|
PrefabUtility.SaveAsPrefabAsset(prefabInstance, prefabPath);
|
||
|
}
|
||
|
|
||
|
// 释放实例
|
||
|
PrefabUtility.UnloadPrefabContents(prefabInstance);
|
||
|
}
|
||
|
|
||
|
Debug.Log($"Total removed missing scripts from selected prefabs: {totalRemovedScripts}");
|
||
|
}
|
||
|
|
||
|
private static int RemoveAllMissingScripts(GameObject obj)
|
||
|
{
|
||
|
int removedCount = 0;
|
||
|
Transform[] transforms = obj.GetComponentsInChildren<Transform>(true);
|
||
|
|
||
|
foreach (Transform t in transforms)
|
||
|
{
|
||
|
Component[] components = t.gameObject.GetComponents<Component>();
|
||
|
|
||
|
SerializedObject so = new SerializedObject(t.gameObject);
|
||
|
SerializedProperty prop = so.FindProperty("m_Component");
|
||
|
|
||
|
int nullCount = 0;
|
||
|
|
||
|
for (int i = 0; i < components.Length; i++)
|
||
|
{
|
||
|
if (components[i] == null)
|
||
|
{
|
||
|
prop.DeleteArrayElementAtIndex(i - nullCount);
|
||
|
nullCount++;
|
||
|
removedCount++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
so.ApplyModifiedProperties();
|
||
|
}
|
||
|
|
||
|
return removedCount;
|
||
|
}
|
||
|
}
|