IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    [原]解决Unity的 The file \'MemoryStream\' is corrupted! Remove it and launch 崩溃问题

    u010019717发表于 2015-07-30 08:37:39
    love 0

    孙广东   2015.7.30

    问题:   在项目平时删除资源或者脚本资源时产生的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();
        }
    }
    
    
    


    


沪ICP备19023445号-2号
友情链接