123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446 |
- using XGame.Framework.i18n;
- using XGame.Framework.Quality;
- using XGame.Framework.Asset.Addressable;
- using XGame.Framework.Asset.Addressable.Data;
- using System.Collections.Generic;
- using UnityEditor;
- using UnityEngine;
- namespace XGame.Editor.Asset
- {
- internal class AddressableInfoManifest
- {
- private AddressableInfosSo manifest;
- private List<AssetInfo> assetInfos;
- /// <summary>
- /// 多语言资源配置,每次收集资源信息都重置
- /// </summary>
- private Dictionary<long, List<AddressableI18nInfo.I18nData>> i18nInfosMap;
- /// <summary>
- /// Lod资源配置,每次收集资源信息都重置
- /// </summary>
- private Dictionary<long, List<AddressableLodInfo.LodData>> lodInfosMap;
- /// <summary>
- /// 等待二次检测的Asset资源
- /// 由于LOD资源在同一目录下,可能出现lod资源比Origin资源更早记录的情况
- /// 第一次检测时找不到就先记录下来,等所有资源遍历结束再做一次检测
- /// </summary>
- private List<AssetInfo> verifingLodAssets;
- public AddressableClassify ClassifyOperation
- {
- get;
- private set;
- }
- public AddressableInfoManifest(AddressableInfosSo manifest, AddressableClassify classify)
- {
- ClassifyOperation = classify;
- this.manifest = manifest;
- assetInfos = manifest?.GetAssetInfos();
- }
- public bool AddAssetInfo(AssetInfo assetInfo)
- {
- if (manifest == null) return false;
- if (assetInfos == null)
- {
- assetInfos = new List<AssetInfo>();
- }
- var index = assetInfos.FindIndex((a) => a.assetGUID.Equals(assetInfo.assetGUID) || a.addressableName.Equals(assetInfo.addressableName) || a.addressableId == assetInfo.addressableId);
- if (index >= 0)
- {
- Debug.LogError($"Asset Manifest AddAssetInfo Error. Asset Repeat Last:{assetInfos[index]} Next:{assetInfo}");
- return false;
- }
- assetInfos.Add(assetInfo);
- OnAddAssetInfo(assetInfo);
- return true;
- }
- public void RemoveAssetInfoByName(string addressableName)
- {
- if (assetInfos != null)
- {
- var index = assetInfos.FindIndex((a) => a.addressableName.Equals(addressableName));
- if (index >= 0)
- {
- assetInfos.RemoveAt(index);
- }
- }
- }
- public bool TryGetAssetInfoByName(string addressableName, out AssetInfo assetInfo)
- {
- if (assetInfos != null)
- {
- var index = assetInfos.FindIndex((a) => a.addressableName.Equals(addressableName));
- if (index >= 0)
- {
- assetInfo = assetInfos[index];
- return true;
- }
- }
- assetInfo = default;
- return false;
- }
- public bool TryGetAssetInfoByGUID(string guid, out AssetInfo assetInfo)
- {
- if (assetInfos != null)
- {
- var index = assetInfos.FindIndex((a) => a.assetGUID.Equals(guid));
- if (index >= 0)
- {
- assetInfo = assetInfos[index];
- return true;
- }
- }
- assetInfo = default;
- return false;
- }
- public bool ContainsName(string addressableName)
- {
- if (assetInfos != null)
- {
- var index = assetInfos.FindIndex((a) => a.addressableName.Equals(addressableName));
- return index >= 0;
- }
- return false;
- }
- public bool ContainsGUID(string guid)
- {
- if (assetInfos != null)
- {
- var index = assetInfos.FindIndex((a) => a.assetGUID.Equals(guid));
- return index >= 0;
- }
- return false;
- }
- public void Save()
- {
- if (manifest != null)
- {
- VerifyLodAssetsSecond();
- SaveLodInfos();
- SaveI18nInfos();
- manifest.SetAssetInfos(assetInfos != null && assetInfos.Count > 0 ? assetInfos.ToArray() : null);
- }
- }
- public void DisposeInvalidAssets(System.Func<AssetInfo, bool> moveAssetEvent)
- {
- if (assetInfos != null)
- {
- for (int i = assetInfos.Count - 1; i >= 0; i--)
- {
- var assetInfo = assetInfos[i];
- if (!AddressableHelper.IsValidPath(assetInfo.GetAssetPath(), ClassifyOperation))
- {
- Debug.LogWarning($"Invalid Asset:{assetInfo}");
- if (moveAssetEvent != null && moveAssetEvent.Invoke(assetInfo))
- {
- assetInfos.RemoveAt(i);
- }
- }
- }
- }
- }
- public void CollectAddressableAssets(ref IDictionary<string, AddressableClassify> addressableNameMap,
- ref IDictionary<long, AddressableClassify> addressableIdMap,
- ref IDictionary<string, AddressableClassify> guidMap)
- {
- if (assetInfos != null)
- {
- for (int i = 0; i < assetInfos.Count; i++)
- {
- var assetInfo = assetInfos[i];
- //刷新relativePath和assetType
- bool isInResources = AddressableHelper.IsInResources(assetInfo.GetAssetPath(), out assetInfo.relativePath);
- //assetInfo.assetType = isInResources ? AddressableAssetType.Resources : AddressableAssetType.Default;
- assetInfos[i] = assetInfo;
- //
- if (addressableNameMap.ContainsKey(assetInfo.addressableName))
- {
- Debug.LogError($"Addressable Name Repeat. {assetInfo}");
- }
- else
- {
- addressableNameMap.Add(assetInfo.addressableName, ClassifyOperation);
- }
- if (addressableIdMap.ContainsKey(assetInfo.addressableId))
- {
- Debug.LogError($"Addressable ID Repeat. {assetInfo}");
- }
- else
- {
- addressableIdMap.Add(assetInfo.addressableId, ClassifyOperation);
- }
- if (guidMap.ContainsKey(assetInfo.assetGUID))
- {
- Debug.LogError($"Addressable GUID Repeat. {assetInfo}");
- }
- else
- {
- guidMap.Add(assetInfo.assetGUID, ClassifyOperation);
- }
- }
- }
- }
- //private bool IsValidPath(string assetPath)
- //{
- // if (string.IsNullOrEmpty(assetPath))
- // {
- // return false;
- // }
- // switch (ClassifyOperation)
- // {
- // case AddressableClassifyOperation.BuiltIn:
- // if (assetPath.StartsWith(PathDefine.XGamePackageRelative))
- // {
- // //在Package Framework目录下
- // return true;
- // }
- // break;
- // case AddressableClassifyOperation.ResStatic:
- // if (assetPath.StartsWith(PathDefine.ResStaticToAddressable))
- // {
- // //在ResStatic目录下
- // return true;
- // }
- // break;
- // default:
- // if (assetPath.StartsWith(PathDefine.ResAddressableRelative))
- // {
- // //在Res/Addressable目录下
- // return true;
- // }
- // if (assetPath.StartsWith(PathDefine.ResourcesRelative))
- // {
- // //在Resources目录下
- // return true;
- // }
- // break;
- // }
- // return false;
- //}
- private void OnAddAssetInfo(AssetInfo assetInfo)
- {
- if (ClassifyOperation == AddressableClassify.Product)
- {
- //项目资源才需要检测LOD和多语言
- VerifyLodAsset(assetInfo, true);
- VerifyI18nAsset(assetInfo);
- }
- }
- public void RefreshAssetInfoByGUID(string assetGUID)
- {
- if (ClassifyOperation == AddressableClassify.Product)
- {
- if (TryGetAssetInfoByGUID(assetGUID, out var assetInfo))
- {
- OnAddAssetInfo(assetInfo);
- }
- }
- }
- #region i18n
- private void VerifyI18nAsset(AssetInfo assetInfo)
- {
- var assetPath = assetInfo.GetAssetPath();
- var langFlag = AddressableHelper.GetLanguageTypeByAssetPath(assetPath);
- if (langFlag != LanguageType.NONE)
- { // 是多语言
- var originPath = assetPath.Replace($"/{PathDefine.I18nName}/{langFlag.ToName()}", "");
- var originGUID = AssetDatabase.AssetPathToGUID(originPath);
- if (string.IsNullOrEmpty(originGUID) == false && TryGetAssetInfoByGUID(originGUID, out var originAsset))
- {
- AddI18nData(originAsset.addressableId, assetInfo.addressableId, langFlag);
- }
- else
- {
- Debug.LogError($"多语言资源错误,找不到对应的原始资源. {assetInfo} OriginPath:{originPath}");
- }
- }
- }
- private bool AddI18nData(long originId, long i18nId, LanguageType langFlag)
- {
- if (i18nInfosMap == null)
- {
- i18nInfosMap = new Dictionary<long, List<AddressableI18nInfo.I18nData>>();
- }
- if (!i18nInfosMap.TryGetValue(originId, out var lstData))
- {
- lstData = new List<AddressableI18nInfo.I18nData>();
- i18nInfosMap.Add(originId, lstData);
- }
- var index = lstData.FindIndex((a) => a.langFlag == langFlag);
- if (index >= 0)
- {
- var data = lstData[index];
- data.addressableId = i18nId;
- lstData[index] = data;
- }
- else
- {
- lstData.Add(new AddressableI18nInfo.I18nData()
- {
- addressableId = i18nId,
- langFlag = langFlag,
- });
- }
- return true;
- }
- private void SaveI18nInfos()
- {
- if (i18nInfosMap != null && i18nInfosMap.Count > 0)
- {
- AddressableI18nInfo[] i18nInfos = new AddressableI18nInfo[i18nInfosMap.Count];
- var index = 0;
- foreach (var pair in i18nInfosMap)
- {
- var info = new AddressableI18nInfo()
- {
- addressableId = pair.Key,
- i18nDatas = pair.Value.ToArray()
- };
- i18nInfos[index++] = info;
- }
- manifest.SetAddressableI18nInfos(i18nInfos, false);
- }
- else
- {
- manifest.SetAddressableI18nInfos(null, false);
- }
- }
- #endregion
- #region LOD
- /// <summary>
- /// 二次检验lod资源
- /// </summary>
- private void VerifyLodAssetsSecond()
- {
- if (verifingLodAssets != null)
- {
- foreach (var assetInfo in verifingLodAssets)
- {
- VerifyLodAsset(assetInfo, false);
- }
- verifingLodAssets.Clear();
- }
- }
- private void VerifyLodAsset(AssetInfo assetInfo, bool isFirst)
- {
- var assetPath = assetInfo.GetAssetPath();
- if (IsLodAssetPath(assetPath, PathDefine.LodHigh, out var originPath, out var quality) ||
- IsLodAssetPath(assetPath, PathDefine.LodLow, out originPath, out quality))
- {
- Debug.Log($"LOD资源. {assetInfo} OriginPath:{originPath}");
- var originGUID = AssetDatabase.AssetPathToGUID(originPath);
- if (string.IsNullOrEmpty(originGUID) == false && TryGetAssetInfoByGUID(originGUID, out var originAsset))
- {
- AddLodData(originAsset.addressableId, assetInfo.addressableId, quality);
- }
- else if (isFirst)
- {
- //保存起来,等待二次校验
- AddVerifingLodAsset(assetInfo);
- }
- else
- {
- Debug.LogError($"LOD资源错误,找不到对应的原始资源. {assetInfo} OriginPath:{originPath}");
- }
- }
- }
- private void AddVerifingLodAsset(AssetInfo assetInfo)
- {
- if (verifingLodAssets == null)
- {
- verifingLodAssets = new List<AssetInfo>();
- }
- verifingLodAssets.Add(assetInfo);
- }
- private bool IsLodAssetPath(string assetPath, string lodTag, out string originPath, out XGame.Framework.Quality.XQualityLevel quality)
- {
- var fileName = System.IO.Path.GetFileNameWithoutExtension(assetPath);
- if (fileName != null && fileName.ToLower().EndsWith(lodTag))
- {
- var originName = fileName.Substring(0, fileName.Length - lodTag.Length);
- originPath = assetPath.Replace(fileName, originName);
- quality = LodTagToQualityLevel(lodTag);
- return true;
- }
- originPath = string.Empty;
- quality = XGame.Framework.Quality.XQualityLevel.UnKnow;
- return false;
- }
- private XGame.Framework.Quality.XQualityLevel LodTagToQualityLevel(string lodTag)
- {
- if (lodTag.Equals(PathDefine.LodHigh))
- {
- return XGame.Framework.Quality.XQualityLevel.High;
- }
- else if (lodTag.Equals(PathDefine.LodLow))
- {
- return XGame.Framework.Quality.XQualityLevel.Low;
- }
- return XGame.Framework.Quality.XQualityLevel.UnKnow;
- }
- private bool AddLodData(long originId, long lodId, XGame.Framework.Quality.XQualityLevel quality)
- {
- if (lodInfosMap == null)
- {
- lodInfosMap = new Dictionary<long, List<AddressableLodInfo.LodData>>();
- }
- if (!lodInfosMap.TryGetValue(originId, out var lstData))
- {
- lstData = new List<AddressableLodInfo.LodData>();
- lodInfosMap.Add(originId, lstData);
- }
- var index = lstData.FindIndex(data => data.quality == quality);
- if (index >= 0)
- {
- var data = lstData[index];
- data.addressableId = lodId;
- lstData[index] = data;
- }
- else
- {
- lstData.Add(new AddressableLodInfo.LodData()
- {
- addressableId = lodId,
- quality = quality
- });
- }
- return true;
- }
- private void SaveLodInfos()
- {
- if (lodInfosMap != null && lodInfosMap.Count > 0)
- {
- var lodInfos = new AddressableLodInfo[lodInfosMap.Count];
- var index = 0;
- foreach (var pair in lodInfosMap)
- {
- var info = new AddressableLodInfo()
- {
- addressableId = pair.Key,
- lodDatas = pair.Value.ToArray()
- };
- lodInfos[index++] = info;
- }
- manifest.SetAddressableLodInfos(lodInfos, false);
- }
- else
- {
- manifest.SetAddressableLodInfos(null, false);
- }
- }
- #endregion
- }
- }
|