123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- using XGame.Framework.i18n;
- using XGame.Framework.Asset.Addressable;
- using XGame.Framework.Asset.Addressable.Data;
- using System.Collections.Generic;
- using System.IO;
- using UnityEditor;
- using UnityEngine;
- using System.Text;
- namespace XGame.Editor.Asset
- {
- public class AddressableBuildTask
- {
- /// <summary>
- /// 方便其它模块使用
- /// </summary>
- public static void GenManifest()
- {
- var task = new AddressableBuildTask();
- task.Run();
- }
- private IDictionary<AddressableClassify, AddressableInfoManifest> manifests;
- private AddressableInfoManifest backupManifest;
- private IDictionary<string, AddressableClassify> addressableNameMap;
- private IDictionary<long, AddressableClassify> addressableIdMap;
- private IDictionary<string, AddressableClassify> guidMap;
- private AddressableClassify[] queryOrder;
- public AddressableBuildTask()
- {
- manifests = new Dictionary<AddressableClassify, AddressableInfoManifest>();
- addressableNameMap = new Dictionary<string, AddressableClassify>();
- addressableIdMap = new Dictionary<long, AddressableClassify>();
- guidMap = new Dictionary<string, AddressableClassify>();
- queryOrder = new AddressableClassify[] { AddressableClassify.Product, AddressableClassify.BuiltIn, AddressableClassify.Tests };
- }
- private void Init()
- {
- LoadManifest();
- DisposeInvalidAssets();
- CollectAddressableAssets();
- }
- public void Run()
- {
- Init();
- Collect();
- Save();
- GenCustomSearch();
- }
- private void Collect()
- {
- AddressableClassify[] classifys = { AddressableClassify.BuiltIn, AddressableClassify.Product, AddressableClassify.Tests };
- for (int i = 0; i < classifys.Length; i++)
- {
- var classify = classifys[i];
- string[] assetsRoots = AddressableHelper.GetAssetsRoots(classify);
- foreach (var assetsRoot in assetsRoots)
- {
- var i18nName = string.Empty;
- var langFlag = LanguageType.NONE;
- if (classify == AddressableClassify.Product)
- {
- langFlag = AddressableHelper.GetLanguageTypeByAssetPath(assetsRoot);
- if (langFlag != LanguageType.NONE)
- {
- i18nName = langFlag.ToString().ToLower();
- }
- }
- FileUtil.FindFiles(assetsRoot, files =>
- {
- foreach (var file in files)
- {
- var path = FileUtil.ToRelativePath(file);// file.Substring(file.IndexOf("Assets/", StringComparison.Ordinal));
- var guid = AssetDatabase.AssetPathToGUID(path);
- if (ContainsGUID(guid))
- {
- //Debug.Log($"GUID Repeat. Path:{path}");
- if (langFlag != LanguageType.NONE || AddressableHelper.IsLodAssetPath(path))
- { //多语言或者LOD资源
- RefreshAssetInfoByGUID(guid, classify);
- }
- continue;
- }
- string fileName;
- //取备份信息
- if (TryGetBackupAssetInfoByGUID(guid, out var backupInfo))
- {
- fileName = backupInfo.addressableName;
- }
- else
- {
- fileName = AddressableHelper.GetFileName(path);
- if (langFlag != LanguageType.NONE)
- {
- fileName = $"{i18nName}_{fileName}";
- }
- }
- if (ContainsName(fileName))
- {
- //二次校验
- TryGetAssetInfoByName(fileName, out var lastAssetInfo);
- var lastPath = lastAssetInfo.GetAssetPath();
- string temp = string.Empty;
- if (string.IsNullOrEmpty(lastPath))
- {
- Debug.LogError($"Two assets have the same name. But one of the files is missing. Last {lastAssetInfo}. Next Path:{path}");
- }
- else if (path.Equals(lastPath))
- {
- Debug.LogError($"Two assets have the same path. But the GUID is different.Last {lastAssetInfo}. Next Path:{path}");
- }
- else
- {
- var ext = Path.GetExtension(path);
- if (!string.IsNullOrEmpty(ext) && !ext.Equals(Path.GetExtension(lastPath)))
- {
- //后缀不一样
- temp = ($"{fileName}{ext.Replace('.', '_')}").ToLower();
- //if (langFlag != LangFlag.NONE)
- //{
- // temp = $"{i18nName}_{temp}";
- //}
- if (ContainsName(temp))
- {
- temp = string.Empty;
- }
- }
- }
- if (string.IsNullOrEmpty(temp))
- {
- temp = ($"{fileName}_{guid.Substring(0, 8)}").ToLower();
- //if (langFlag != LangFlag.NONE)
- //{
- // temp = $"{i18nName}_{temp}";
- //}
- if (ContainsName(temp))
- {
- temp = ($"{fileName}_{guid}").ToLower();
- //if (langFlag != LangFlag.NONE)
- //{
- // temp = $"{i18nName}_{temp}";
- //}
- }
- }
- fileName = temp;
- }
- //addressableId使用guid+path,预防相同路径的情况
- var isInResources = AddressableHelper.IsInResources(path, out var relativePath);
- //var assetType = isInResources ? AddressableAssetType.Resources : AddressableAssetType.Default;
- var assetInfo = new AssetInfo()
- {
- addressableId = Crc32.GetCrc32($"{guid}+{path}"),
- addressableName = fileName,
- assetGUID = guid,
- //assetType = assetType,
- relativePath = relativePath,
- };
- if (AddAssetInfo(assetInfo))
- {
- Debug.Log($"guid:{guid} name:{fileName} path:{path}");
- }
- }
- });
- }
- }
- }
- private void Save()
- {
- for (int i = 0; i < queryOrder.Length; i++)
- {
- if (manifests.TryGetValue(queryOrder[i], out var manifest))
- {
- manifest.Save();
- }
- }
- backupManifest.Save();
- }
- public bool TryGetAssetInfoByName(string addressableName, out AssetInfo assetInfo)
- {
- if (addressableNameMap.TryGetValue(addressableName, out var classify))
- {
- if (manifests[classify].TryGetAssetInfoByName(addressableName, out var tempAsset))
- {
- assetInfo = tempAsset;
- return true;
- }
- }
- assetInfo = default;
- return false;
- }
- public bool TryGetBackupAssetInfoByGUID(string guid, out AssetInfo assetInfo)
- {
- if (backupManifest.TryGetAssetInfoByGUID(guid, out var tempAsset))
- {
- assetInfo = tempAsset;
- return true;
- }
- assetInfo = default;
- return false;
- }
- private bool ContainsName(string addressableName)
- {
- if (addressableNameMap.ContainsKey(addressableName))
- {
- return true;
- }
- //for (int i = 0; i < queryOrder.Length; i++)
- //{
- // if (manifests.TryGetValue(queryOrder[i], out var manifest))
- // {
- // if (manifest.ContainsName(addressableName))
- // {
- // return true;
- // }
- // }
- //}
- return false;
- }
- private bool ContainsGUID(string guid)
- {
- if (guidMap.ContainsKey(guid))
- {
- return true;
- }
- //for (int i = 0; i < queryOrder.Length; i++)
- //{
- // if (manifests.TryGetValue(queryOrder[i], out var manifest))
- // {
- // if (manifest.ContainsGUID(guid))
- // {
- // return true;
- // }
- // }
- //}
- return false;
- }
- private void RefreshAssetInfoByGUID(string guid, AddressableClassify classify)
- {
- if (manifests.TryGetValue(classify, out var manifest))
- {
- manifest.RefreshAssetInfoByGUID(guid);
- }
- }
- private bool AddAssetInfo(AssetInfo assetInfo)
- {
- var assetPath = assetInfo.GetAssetPath();
- if (AddressableHelper.TryAssetPathToClassify(assetPath, out var classify))
- {
- if (manifests.TryGetValue(classify, out var manifest))
- {
- if (manifest.AddAssetInfo(assetInfo))
- {
- AddAddressableName(assetInfo.addressableName, classify);
- AddAddressableId(assetInfo.addressableId, classify);
- AddAssetGUID(assetInfo.assetGUID, classify);
- return true;
- }
- }
- }
- return false;
- }
- private void LoadManifest()
- {
- for (int i = 0; i < queryOrder.Length; i++)
- {
- var classify = queryOrder[i];
- var manifest = CreateManifest(classify);
- if (manifest != null)
- manifests.Add(classify, manifest);
- }
- backupManifest = CreateManifest(AddressableClassify.Backup);
- }
- private AddressableInfoManifest CreateManifest(AddressableClassify classify)
- {
- var manifest = AddressableHelper.LoadOrCreateManifest(classify);
- if (manifest != null)
- {
- var adapter = new AddressableInfoManifest(manifest, classify);
- return adapter;
- }
- return null;
- }
- private void DisposeInvalidAssets()
- {
- for (int i = 0; i < queryOrder.Length; i++)
- {
- if (manifests.TryGetValue(queryOrder[i], out var manifest))
- {
- manifest.DisposeInvalidAssets(AddAssetInfo);
- }
- }
- }
- private void CollectAddressableAssets()
- {
- addressableNameMap.Clear();
- addressableIdMap.Clear();
- guidMap.Clear();
- for (int i = 0; i < queryOrder.Length; i++)
- {
- if (manifests.TryGetValue(queryOrder[i], out var manifest))
- {
- manifest.CollectAddressableAssets(ref addressableNameMap, ref addressableIdMap, ref guidMap);
- }
- }
- }
- private void AddAddressableName(string addressableName, AddressableClassify classify)
- {
- if (addressableNameMap.ContainsKey(addressableName))
- {
- addressableNameMap[addressableName] = classify;
- }
- else
- {
- addressableNameMap.Add(addressableName, classify);
- }
- }
- private void AddAssetGUID(string guid, AddressableClassify classify)
- {
- if (guidMap.ContainsKey(guid))
- {
- guidMap[guid] = classify;
- }
- else
- {
- guidMap.Add(guid, classify);
- }
- }
- private void AddAddressableId(long id, AddressableClassify classify)
- {
- if (addressableIdMap.ContainsKey(id))
- {
- addressableIdMap[id] = classify;
- }
- else
- {
- addressableIdMap.Add(id, classify);
- }
- }
- #region 资源搜索和引用标签 https://docs.unity.cn/cn/tuanjiemanual/1.2/Manual/AssetsReferences.html
- /// <summary>
- /// 生成CustomSearch.txt
- /// </summary>
- private void GenCustomSearch()
- {
- var manifest = AddressableHelper.LoadAssetManifest(AddressableClassify.Product);
- var assetInfos = manifest.assetInfos;
- var assetPaths = new List<string>();
- for(var i = 0; i < assetInfos.Length; i++)
- {
- var assetPath = assetInfos[i].GetAssetPath();
- if (string.IsNullOrEmpty(assetPath))
- {
- continue;
- }
- assetPaths.Add(assetPath);
- }
- var sb = new StringBuilder();
- sb.AppendLine((assetPaths.Count + 4).ToString());
- for(var i = 0;i < assetPaths.Count; i++)
- {
- sb.AppendLine(assetPaths[i]);
- }
- sb.AppendLine(PathDefine.BundleManifestPath);
- sb.AppendLine(PathDefine.SceneAssetBundleManifestPath);
- sb.AppendLine(PathDefine.ReferenceManifestPath);
- sb.AppendLine(PathDefine.ProductAssetManifestPath);
- var filePath = PathDefine.AddressableDataRelative + "CustomSearch.txt";
- File.WriteAllText(filePath, sb.ToString());
- AssetDatabase.Refresh();
- }
- #endregion
- }
- }
|