解决Unity的The file 'MemoryStream' is corrupted! 崩溃问题
发表于2017-10-14
问题: 在项目平时删除资源或者脚本资源时产生的prefab的脚本引用丢失,特别是在场景scene中丢了
解决方案
/// 1、重新Clone项目
/// 2、删除项目的 Library 文件夹(推荐、解决紧急问题)
/// 3、使用这个脚本解决所有问题(这个当然推荐了)
http://forum.unity3d.com/threads/editor-want-to-check-all-prefabs-in-a-project-for-an-attached-monobehaviour.253149/#post-1673716
- 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);
- }
- }
- }
- break;
- case 1:
- List<string> scenesToLoad = new List<string>();
- existingComponents = new List<ComponentNames>();
- prefabComponents = new List<ComponentNames>();
- notUsedComponents = new List<ComponentNames>();
- addedComponents = new List<ComponentNames>();
- sceneComponents = new List<ComponentNames>();
- if (EditorApplication.SaveCurrentSceneIfUserWantsTo())
- {
- string projectPath = Application.dataPath;
- projectPath = projectPath.Substring(0, projectPath.IndexOf("Assets"));
- string[] allAssets = AssetDatabase.GetAllAssetPaths();
- foreach (string asset in allAssets)
- {
- int indexCS = asset.IndexOf(".cs");
- int indexJS = asset.IndexOf(".js");
- if (indexCS != -1 || indexJS != -1)
- {
- ComponentNames newComponent = new ComponentNames(NameFromPath(asset), "", asset);
- try
- {
- System.IO.FileStream FS = new System.IO.FileStream(projectPath asset, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
- System.IO.StreamReader SR = new System.IO.StreamReader(FS);
- string line;
- while (!SR.EndOfStream)
- {
- line = SR.ReadLine();
- int index1 = line.IndexOf("namespace");
- int index2 = line.IndexOf("{");
- if (index1 != -1 && index2 != -1)
- {
- line = line.Substring(index1 9);
- index2 = line.IndexOf("{");
- line = line.Substring(0, index2);
- line = line.Replace(" ", "");
- newComponent.namespaceName = line;
- }
- }
- }
- catch
- {
- }
- existingComponents.Add(newComponent);
- try
- {
- System.IO.FileStream FS = new System.IO.FileStream(projectPath asset, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.ReadWrite);
- System.IO.StreamReader SR = new System.IO.StreamReader(FS);
- string line;
- int lineNum = 0;
- while (!SR.EndOfStream)
- {
- lineNum ;
- line = SR.ReadLine();
- int index = line.IndexOf("AddComponent");
- if (index != -1)
- {
- line = line.Substring(index 12);
- if (line[0] == '(')
- {
- line = line.Substring(1, line.IndexOf(')') - 1);
- }
- else if (line[0] == '<')
- {
- line = line.Substring(1, line.IndexOf('>') - 1);
- }
- else
- {
- continue;
- }
- line = line.Replace(" ", "");
- line = line.Replace("\"", "");
- index = line.LastIndexOf('.');
- ComponentNames newComp;
- if (index == -1)
- {
- newComp = new ComponentNames(line, "", "");
- }
- else
- {
- newComp = new ComponentNames(line.Substring(index 1, line.Length - (index 1)), line.Substring(0, index), "");
- }
- string pName = asset ", Line " lineNum;
- newComp.usageSource.Add(pName);
- index = addedComponents.IndexOf(newComp);
- if (index == -1)
- {
- addedComponents.Add(newComp);
- }
- else
- {
- if (!addedComponents[index].usageSource.Contains(pName)) addedComponents[index].usageSource.Add(pName);
- }
- }
- }
- }
- catch
- {
- }
- }
- int indexPrefab = asset.IndexOf(".prefab");
- if (indexPrefab != -1)
- {
- string[] single = new string[] { asset };
- string[] dependencies = AssetDatabase.GetDependencies(single);
- foreach (string dependedAsset in dependencies)
- {
- if (dependedAsset.IndexOf(".cs") != -1 || dependedAsset.IndexOf(".js") != -1)
- {
- ComponentNames newComponent = new ComponentNames(NameFromPath(dependedAsset), GetNamespaceFromPath(dependedAsset), dependedAsset);
- int index = prefabComponents.IndexOf(newComponent);
- if (index == -1)
- {
- newComponent.usageSource.Add(asset);
- prefabComponents.Add(newComponent);
- }
- else
- {
- if (!prefabComponents[index].usageSource.Contains(asset)) prefabComponents[index].usageSource.Add(asset);
- }
- }
- }
- }
- int indexUnity = asset.IndexOf(".unity");
- if (indexUnity != -1)
- {
- scenesToLoad.Add(asset);
- }
- }
- for (int i = addedComponents.Count - 1; i > -1; i--)
- {
- addedComponents[i].assetPath = GetPathFromNames(addedComponents[i].namespaceName, addedComponents[i].componentName);
- if (addedComponents[i].assetPath == "") addedComponents.RemoveAt(i);
- }
- foreach (string scene in scenesToLoad)
- {
- EditorApplication.OpenScene(scene);
- GameObject[] sceneGOs = GetAllObjectsInScene();
- foreach (GameObject g in sceneGOs)
- {
- Component[] comps = g.GetComponentsInChildren<Component>(true);
- foreach (Component c in comps)
- {
- if (c != null && c.GetType() != null && c.GetType().BaseType != null && c.GetType().BaseType == typeof(MonoBehaviour))
- {
- SerializedObject so = new SerializedObject(c);
- SerializedProperty p = so.FindProperty("m_Script");
- string path = AssetDatabase.GetAssetPath(p.objectReferenceValue);
- ComponentNames newComp = new ComponentNames(NameFromPath(path), GetNamespaceFromPath(path), path);
- newComp.usageSource.Add(scene);
- int index = sceneComponents.IndexOf(newComp);
- if (index == -1)
- {
- sceneComponents.Add(newComp);
- }
- else
- {
- if (!sceneComponents[index].usageSource.Contains(scene)) sceneComponents[index].usageSource.Add(scene);
- }
- }
- }
- }
- }
- foreach (ComponentNames c in existingComponents)
- {
- if (addedComponents.Contains(c)) continue;
- if (prefabComponents.Contains(c)) continue;
- if (sceneComponents.Contains(c)) continue;
- notUsedComponents.Add(c);
- }
- addedComponents.Sort(SortAlphabetically);
- prefabComponents.Sort(SortAlphabetically);
- sceneComponents.Sort(SortAlphabetically);
- notUsedComponents.Sort(SortAlphabetically);
- }
- break;
- }
- }
- break;
- case 1:
- if (GUILayout.Button("Search!"))
- {
- string[] allPrefabs = GetAllPrefabs();
- listResult = new List<string>();
- foreach (string prefab in allPrefabs)
- {
- UnityEngine.Object o = AssetDatabase.LoadMainAssetAtPath(prefab);
- GameObject go;
- try
- {
- go = (GameObject)o;
- Component[] components = go.GetComponentsInChildren<Component>(true);
- foreach (Component c in components)
- {
- if (c == null)
- {
- listResult.Add(prefab);
- }
- }
- }
- catch
- {
- Debug.Log("For some reason, prefab " prefab " won't cast to GameObject");
- }
- }
- }
- break;
- }
- if (editorMode == 1 || selectedCheckType == 0)
- {
- if (listResult != null)
- {
- if (listResult.Count == 0)
- {
- GUILayout.Label(editorMode == 0 ? (componentName == "" ? "Choose a component" : "No prefabs use component " componentName) : ("No prefabs have missing components!\nClick Search to check again"));
- }
- else
- {
- GUILayout.Label(editorMode == 0 ? ("The following prefabs use component " componentName ":") : ("The following prefabs have missing components:"));
- scroll = GUILayout.BeginScrollView(scroll);
- foreach (string s in listResult)
- {
- GUILayout.BeginHorizontal();
- GUILayout.Label(s, GUILayout.Width(position.width / 2));
- if (GUILayout.Button("Select", GUILayout.Width(position.width / 2 - 10)))
- {
- Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(s);
- }
- GUILayout.EndHorizontal();
- }
- GUILayout.EndScrollView();
- }
- }
- }
- else
- {
- showPrefabs = GUILayout.Toggle(showPrefabs, "Show prefab components");
- if (showPrefabs)
- {
- GUILayout.Label("The following components are attatched to prefabs:");
- DisplayResults(ref scroll1, ref prefabComponents);
- }
- showAdded = GUILayout.Toggle(showAdded, "Show AddComponent arguments");
- if (showAdded)
- {
- GUILayout.Label("The following components are AddComponent arguments:");
- DisplayResults(ref scroll2, ref addedComponents);
- }
- showScene = GUILayout.Toggle(showScene, "Show Scene-used components");
- if (showScene)
- {
- GUILayout.Label("The following components are used by scene objects:");
- DisplayResults(ref scroll3, ref sceneComponents);
- }
- showUnused = GUILayout.Toggle(showUnused, "Show Unused Components");
- if (showUnused)
- {
- GUILayout.Label("The following components are not used by prefabs, by AddComponent, OR in any scene:");
- DisplayResults(ref scroll4, ref notUsedComponents);
- }
- }
- }
- int SortAlphabetically(ComponentNames a, ComponentNames b)
- {
- return a.assetPath.CompareTo(b.assetPath);
- }
- GameObject[] GetAllObjectsInScene()
- {
- List<GameObject> objectsInScene = new List<GameObject>();
- GameObject[] allGOs = (GameObject[])Resources.FindObjectsOfTypeAll(typeof(GameObject));
- foreach (GameObject go in allGOs)
- {
- //if ( go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave )
- // continue;
- string assetPath = AssetDatabase.GetAssetPath(go.transform.root.gameObject);
- if (!string.IsNullOrEmpty(assetPath))
- continue;
- objectsInScene.Add(go);
- }
- return objectsInScene.ToArray();
- }
- void DisplayResults(ref Vector2 scroller, ref List<ComponentNames> list)
- {
- if (list == null) return;
- scroller = GUILayout.BeginScrollView(scroller);
- foreach (ComponentNames c in list)
- {
- GUILayout.BeginHorizontal();
- GUILayout.Label(c.assetPath, GUILayout.Width(position.width / 5 * 4));
- if (GUILayout.Button("Select", GUILayout.Width(position.width / 5 - 30)))
- {
- Selection.activeObject = AssetDatabase.LoadMainAssetAtPath(c.assetPath);
- }
- GUILayout.EndHorizontal();
- if (c.usageSource.Count == 1)
- {
- GUILayout.Label(" In 1 Place: " c.usageSource[0]);
- }
- if (c.usageSource.Count > 1)
- {
- GUILayout.Label(" In " c.usageSource.Count " Places: " c.usageSource[0] ", " c.usageSource[1] (c.usageSource.Count > 2 ? ", ..." : ""));
- }
- }
- GUILayout.EndScrollView();
- }
- string NameFromPath(string s)
- {
- s = s.Substring(s.LastIndexOf('/') 1);
- return s.Substring(0, s.Length - 3);
- }
- string GetNamespaceFromPath(string path)
- {
- foreach (ComponentNames c in existingComponents)
- {
- if (c.assetPath == path)
- {
- return c.namespaceName;
- }
- }
- return "";
- }
- string GetPathFromNames(string space, string name)
- {
- ComponentNames test = new ComponentNames(name, space, "");
- int index = existingComponents.IndexOf(test);
- if (index != -1)
- {
- return existingComponents[index].assetPath;
- }
- return "";
- }
- public static string[] GetAllPrefabs()
- {
- string[] temp = AssetDatabase.GetAllAssetPaths();
- List<string> result = new List<string>();
- foreach (string s in temp)
- {
- if (s.Contains(".prefab")) result.Add(s);
- }
- return result.ToArray();
- }
- }
http://blog.csdn.net/u010019717/article/details/47125795
