问题: Unity2018升级到Unity2021后,打图集时新增图片的internalID为0(图1),左边是未修改之前的meta文件信息。导致将图片推拽到预制之后,预制没有正确保存图片信息(图2),游戏运行后加载预制图片为空。
版本:Unity 2018.4.36f1 升级到 Unity 2021.3.19f1
图集工具:TexturePacker
修改思路:因为未找到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<SerializedProperty> _changeSPList = new List<SerializedProperty>();
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<string, long> _tempNameFileIdTableDic = new Dictionary<string, long>();
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的规则。