using System; using System.Collections.Generic; using System.Linq; using UnityEditor.AddressableAssets.Build.DataBuilders; using UnityEditor.Build.Content; using UnityEditor.Build.Pipeline; using UnityEditor.Build.Pipeline.Injector; using UnityEditor.Build.Pipeline.Interfaces; using UnityEditor.Build.Pipeline.Utilities; using UnityEngine; namespace UnityEditor.AddressableAssets.Build.BuildPipelineTasks { /// /// The BuildTask used to append the asset hash to the internal bundle name. /// public class AddHashToBundleNameTask : IBuildTask { /// /// The task version. /// public int Version { get { return 1; } } #pragma warning disable 649 [InjectContext(ContextUsage.In)] IBuildParameters m_Parameters; [InjectContext(ContextUsage.In)] IBundleBuildContent m_BuildContent; [InjectContext] IDependencyData m_DependencyData; [InjectContext(ContextUsage.InOut, true)] IBuildSpriteData m_SpriteData; [InjectContext(ContextUsage.In)] IAddressableAssetsBuildContext m_AaBuildContext; [InjectContext(ContextUsage.In, true)] IBuildCache m_Cache; #pragma warning restore 649 /// /// Runs the AddHashToBundleNameTask. /// /// Success. public ReturnCode Run() { var aa = m_AaBuildContext as AddressableAssetsBuildContext; if (!aa.Settings.UniqueBundleIds) return ReturnCode.Success; var newBundleLayout = new Dictionary>(); foreach (var bid in m_BuildContent.BundleLayout) { var hash = GetAssetsHash(bid.Value, aa); var newName = $"{bid.Key}_{hash}"; newBundleLayout.Add(newName, bid.Value); string assetGroup; if (aa.bundleToAssetGroup.TryGetValue(bid.Key, out assetGroup)) { aa.bundleToAssetGroup.Remove(bid.Key); aa.bundleToAssetGroup.Add(newName, assetGroup); } } m_BuildContent.BundleLayout.Clear(); foreach (var bid in newBundleLayout) m_BuildContent.BundleLayout.Add(bid.Key, bid.Value); return ReturnCode.Success; } internal RawHash GetAssetsHash(List assets, AddressableAssetsBuildContext context) { assets.Sort(); var hashes = new HashSet(); foreach (var g in assets) { AssetLoadInfo assetInfo; if (m_DependencyData.AssetInfo.TryGetValue(g, out assetInfo)) { var diskOnlyReferencedObjects = assetInfo.referencedObjects.Where(ro => context.Settings.FindAssetEntry(ro.guid.ToString()) == null).ToList(); GetAssetHashes(hashes, g, diskOnlyReferencedObjects, m_Cache != null && m_Parameters.UseCache); } } return HashingMethods.Calculate(hashes.ToArray()); } void GetAssetHashes(HashSet hashes, GUID g, List referencedObjects, bool useCache) { if (useCache) { hashes.Add(m_Cache.GetCacheEntry(g, Version).Hash); foreach (var reference in referencedObjects) hashes.Add(m_Cache.GetCacheEntry(reference).Hash); } else hashes.Add(AssetDatabase.GetAssetDependencyHash(AssetDatabase.GUIDToAssetPath(g.ToString()))); } } }