孙广东 2015.7.30
问题: 在项目平时删除资源或者脚本资源时产生的prefab的脚本引用丢失,特别是在场景scene中丢了
解决方案
/// 1、重新Clone项目
/// 2、删除项目的 Library 文件夹(推荐、解决紧急问题)
/// 3、使用这个脚本解决所有问题(这个当然推荐了)
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// 查看 prefab的脚本引用丢失
/// 像 : The file 'MemoryStream' is corrupted! Remove it and launch unity again! [Position out of bounds! 20 > 16] 崩溃问题
///
/// http://forum.unity3d.com/threads/unity-4-5-memory-stream-is-corrupted.248356/
/// http://forum.unity3d.com/threads/editor-want-to-check-all-prefabs-in-a-project-for-an-attached-monobehaviour.253149/#post-1673716
/// </summary>
public class SearchForComponents : EditorWindow
{
[MenuItem("DajiaGame/Search For Components")]
static void Init()
{
SearchForComponents window = (SearchForComponents)EditorWindow.GetWindow(typeof(SearchForComponents));
window.Show();
window.position = new Rect(20, 80, 550, 500);
}
string[] modes = new string[] { "Search for component usage", "Search for missing components" };
string[] checkType = new string[] { "Check single component", "Check all components" };
List<string> listResult;
List<ComponentNames> prefabComponents, notUsedComponents, addedComponents, existingComponents, sceneComponents;
int editorMode, selectedCheckType;
MonoScript targetComponent;
string componentName = "";
bool showPrefabs, showAdded, showScene, showUnused = true;
Vector2 scroll, scroll1, scroll2, scroll3, scroll4;
class ComponentNames
{
public string componentName;
public string namespaceName;
public string assetPath;
public List<string> usageSource;
public ComponentNames(string comp, string space, string path)
{
this.componentName = comp;
this.namespaceName = space;
this.assetPath = path;
this.usageSource = new List<string>();
}
public override bool Equals(object obj)
{
return ((ComponentNames)obj).componentName == componentName && ((ComponentNames)obj).namespaceName == namespaceName;
}
public override int GetHashCode()
{
return componentName.GetHashCode() + namespaceName.GetHashCode();
}
}
void OnGUI()
{
GUILayout.Label(position + "");
GUILayout.Space(3);
int oldValue = GUI.skin.window.padding.bottom;
GUI.skin.window.padding.bottom = -20;
Rect windowRect = GUILayoutUtility.GetRect(1, 17);
windowRect.x += 4;
windowRect.width -= 7;
editorMode = GUI.SelectionGrid(windowRect, editorMode, modes, 2, "Window");
GUI.skin.window.padding.bottom = oldValue;
switch (editorMode)
{
case 0:
selectedCheckType = GUILayout.SelectionGrid(selectedCheckType, checkType, 2, "Toggle");
GUI.enabled = selectedCheckType == 0;
targetComponent = (MonoScript)EditorGUILayout.ObjectField(targetComponent, typeof(MonoScript), false);
GUI.enabled = true;
if (GUILayout.Button("Check component usage"))
{
AssetDatabase.SaveAssets();
switch (selectedCheckType)
{
case 0:
componentName = targetComponent.name;
string targetPath = AssetDatabase.GetAssetPath(targetComponent);
string[] allPrefabs = GetAllPrefabs();
listResult = new List<string>();
foreach (string prefab in allPrefabs)
{
string[] single = new string[] { prefab };
string[] dependencies = AssetDatabase.GetDependencies(single);
foreach (string dependedAsset in dependencies)
{
if (dependedAsset == targetPath)
{
listResult.Add(prefab);
}
}