【Unity编辑器扩展实践】升级Unity2021版本后新加图片打图集异常

问题: Unity2018升级到Unity2021后,打图集时新增图片的internalID为0(图1),左边是未修改之前的meta文件信息。导致将图片推拽到预制之后,预制没有正确保存图片信息(图2),游戏运行后加载预制图片为空。

版本:Unity 2018.4.36f1  升级到 Unity 2021.3.19f1

图集工具:TexturePacker

【Unity编辑器扩展实践】升级Unity2021版本后新加图片打图集异常_第1张图片 图1、图片meta修改前后对比 【Unity编辑器扩展实践】升级Unity2021版本后新加图片打图集异常_第2张图片 图2、预制修改前后对比

 修改思路:因为未找到InternalID为0的具体原因,所以在准备修改该internalID。在图集数据生成之后,遍历Sprite,如果m_SpriteID为00000000000000000800000000000000,用GUID.Generate()生成一个m_SpriteID。如果m_InternalID为0,用m_SpriteID.GetHashCode()生成一个m_InternalID。循环遍历修改过的SerializedProperty,修改m_InternalIDToNameTable和nameFileIdTable,保存meta文件。

具体代码:

private static void DoApply()
    {
        string path = AssetDatabase.GetAssetPath(rgbImage);
        TextureImporter textureImporter = AssetImporter.GetAtPath(path) as TextureImporter;
        var m_CachedSerializedObject = new SerializedObject(textureImporter);
        m_CachedSerializedObject?.Update();
        var _nameTable = m_CachedSerializedObject.FindProperty("m_InternalIDToNameTable");
        if (_nameTable.arraySize > 0)//旧图集
        {
            var spriteSheetSo = m_CachedSerializedObject.FindProperty("m_SpriteSheet.m_Sprites");
            if (spriteSheetSo.arraySize > 0)
            {
                List _changeSPList = new List();
                SerializedProperty sp = null;
                for (int i = 0; i < spriteSheetSo.arraySize; ++i)
                {
                    sp = spriteSheetSo.GetArrayElementAtIndex(i);
                    if ("00000000000000000800000000000000" == sp.FindPropertyRelative("m_SpriteID").stringValue)
                    {
                        _changeSPList.Add(sp);
                        string _guid = GUID.Generate().ToString();
                        sp.FindPropertyRelative("m_SpriteID").stringValue = _guid;
                        if (sp.FindPropertyRelative("m_InternalID").longValue == 0)
                        {
                            sp.FindPropertyRelative("m_InternalID").longValue = _guid.GetHashCode();
                        }
                    }
                }
                if (_changeSPList.Count > 0)
                {
                    Dictionary _tempNameFileIdTableDic = new Dictionary();
                    int _index = _nameTable.arraySize;
                    for (int i = 0; i < _changeSPList.Count; i++)//修改m_InternalIDToNameTable
                    {
                        _nameTable.InsertArrayElementAtIndex(_index + i);
                        string _spriteName = _changeSPList[i].FindPropertyRelative("m_Name").stringValue;
                        long _internalID = _changeSPList[i].FindPropertyRelative("m_InternalID").longValue;
                        var _nameTableTemp = _nameTable.GetArrayElementAtIndex(_index + i);
                        _nameTableTemp.FindPropertyRelative("first.second").longValue = _internalID;
                        _nameTableTemp.FindPropertyRelative("second").stringValue = _spriteName;
                        _tempNameFileIdTableDic[_spriteName] = _internalID;
                    }
                    var nameTableSp = m_CachedSerializedObject.FindProperty("m_SpriteSheet.m_NameFileIdTable");
                    if (nameTableSp.arraySize > 0)//修改nameFileIdTable
                    {
                        SerializedProperty nameSp = nameTableSp.GetArrayElementAtIndex(0);
                        for (int i = 0; i < nameTableSp.arraySize; i++)
                        {
                            if (nameSp.FindPropertyRelative("second").longValue == 0)
                            {
                                string _name = nameSp.FindPropertyRelative("first").stringValue;
                                nameSp.FindPropertyRelative("second").longValue = _tempNameFileIdTableDic[_name];
                            }
                            nameSp.Next(false);
                        }
                    }
                    m_CachedSerializedObject.ApplyModifiedProperties();
                    AssetDatabase.ForceReserializeAssets(new[] { path }, ForceReserializeAssetsOptions.ReserializeMetadata);

                }
            }
        }
    }

然后重新分离图集,即可修改InternalID为0的值。

注:该SpriteID生成规则和Unity生成规则不一致,没有找到Unity生成SpriteID的规则。

你可能感兴趣的:(Unity编辑器扩展,unity,游戏引擎,编辑器)