The file 'MemoryStream' is corrupted! 的解决办法

本文提供了一个Unity编辑器脚本,用于查找项目中丢失组件引用的Prefab。通过该脚本,开发者可以轻松定位并修复丢失引用的问题,避免因错误而导致的Unity崩溃。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

The file 'MemoryStream' is corrupted! Remove it and launch unity again!
[Position out of bounds! 20 > 16]

有时候我们会遇到这个报错,然后整个U3D就崩溃了,原因是在于某些Prefabs的脚本引用丢失了,这个时候,只要把项目的所有丢失引用的Prefabs问题都解决了就OK了。

那么问题来了,有几万个Prefab也手动去解决吗,不!这里有个方便你检查丢失引用的脚本,用这个就可以检查出所有的丢失Prefab了,需要注意的是有一些被列举出来的Prefab虽然没有丢失引用,然后是它的子项目丢失引用了,这个脚本是无法把哪一个子game object指出来的,这个时候,迩只能把指定的丢失的prefab拖到U3D的Hierarchy下然后仔细把所有的丢失引用问题解决就好了。

如果一个丢失引用的Prefab迩拖到Hierarchy时它是不是显示是蓝色的,如果迩修复了所有的引用,点一下Apply看看是否变成蓝色,如果是的话那证明这个Prefab的所有丢失引用问题已经解决了。

//Assets/Editor/SearchForComponents.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

public class SearchForComponents : EditorWindow {
    [MenuItem( "EDITORS/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://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

<think>好的,我现在需要解决用户提出的Unity项目文件损坏或版本不兼容的问题。用户提到遇到类似“The file 'MemoryStream' is corrupted!”或“serialized with newer version”的错误。首先,我得回忆一下之前处理这类问题的经验,并结合提供的引用内容来组织解决方案。 首先,根据引用[5],删除Library文件夹可以解决某些文件损坏问题。这应该是第一步,因为Library文件夹包含了Unity自动生成的元数据和缓存,删除后Unity会重新生成,可能修复损坏的文件。但用户需要注意备份项目,避免意外数据丢失,虽然通常不会影响Assets或ProjectSettings,但谨慎总没错。 接下来,引用[4]中提到删除Library文件夹是推荐的解决方法之一,同时提到重新克隆项目或使用脚本修复丢失的引用。如果用户使用版本控制(比如Git),重新克隆项目可能有效,但如果是本地项目,可能需要先尝试删除Library。此外,脚本引用丢失的问题可能与文件损坏有关,所以清理Library可能同时解决这两个问题。 然后,关于版本不兼容的问题,比如提示需要新版本Unity,引用[2]提到自动更新失败时需要手动下载安装包。因此,用户可能需要检查Unity版本是否与项目要求的匹配。如果项目是用较新版本的Unity创建的,而用户使用的是旧版本,就需要升级Unity。这时候需要到Unity官网下载对应的版本安装程序,或者根据错误提示中的URL手动下载所需的Web Player(虽然Web Player现在可能已经过时了)。 另外,引用[3]中提到了资源加载的方式,如果资源在序列化过程中损坏,可能需要重新导入或替换损坏的预制体或场景文件。用户可以尝试在AssetBundles中重新加载资源,或者检查特定预制体是否有问题,必要时从备份恢复。 还需要考虑资源文件本身是否损坏。用户需要检查最近修改过的文件,比如场景、预制体或脚本,尝试逐个排除。如果某个文件无法打开,可能需要从版本控制中恢复或手动修复其内容。 最后,预防措施也很重要。建议用户定期备份项目,尤其是使用版本控制系统,并保持Unity版本更新以避免兼容性问题。同时,避免直接删除项目文件,而是通过Unity编辑器进行操作,减少引用丢失的风险。 现在,我需要将这些步骤整理成一个清晰的解决方案,分步骤说明,并确保引用的内容正确标注。同时,生成相关问题,帮助用户进一步了解可能相关的其他问题。</think>### 解决Unity文件损坏或版本不兼容问题的方法 #### 1. **清理并重新生成项目缓存** - **删除`Library`文件夹**:Unity在编译时会生成大量缓存文件,若这些文件损坏会导致加载错误。关闭Unity编辑器后,手动删除项目根目录下的`Library`文件夹(此操作不会影响原始资源文件),重启Unity时会自动重建缓存[^4][^5]。 - **操作示例**: ```bash # 在项目路径下执行(Windows示例) rm -rf ./Library ``` #### 2. **修复版本不兼容问题** - **升级Unity编辑器**:若提示“serialized with newer version”,说明项目是用更高版本的Unity创建的。需到[Unity官网](https://unity.com/releases)下载对应版本安装程序。 - **手动下载依赖包**:若遇到类似“auto-update failed”错误(如旧版Web Player),可根据提示URL手动下载并安装依赖包[^2]。 #### 3. **修复损坏的资产文件** - **重新导入资源**:选中损坏的资产(如场景、预制体),右键选择`Reimport`。 - **替换损坏文件**:若文件内容损坏(如`.prefab`或`.scene`文件显示乱码),需从备份或版本控制(如Git)中恢复原始文件[^4]。 - **脚本引用丢失修复**:若Prefab因脚本删除导致引用丢失,可通过脚本批量修复或重新关联组件[^4]。 #### 4. **检查项目完整性** - **验证文件结构**:确保关键文件夹(如`Assets`、`ProjectSettings`)未被误删或移动。 - **使用日志定位问题**:查看`Editor.log`(路径:`C:\Users\<用户名>\AppData\Local\Unity\Editor\Editor.log`)中的具体错误信息。 #### 5. **预防措施** - **定期备份**:使用Git、SVN或云存储保存项目历史版本。 - **统一开发环境**:团队协作时确保所有成员使用相同Unity版本。 - **避免直接删除文件**:通过Unity编辑器删除资源,防止元数据残留导致引用错误。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值