using System; using UnityEditor.Build.Content; using UnityEditor.Build.Pipeline.Interfaces; using UnityEditor.Build.Pipeline.Utilities; namespace UnityEditor.Build.Pipeline { /// /// Generates a deterministic identifier using a MD5 hash algorithm and does not require object ordering to be deterministic. /// This algorithm ensures objects coming from the same asset are packed closer together and can improve loading performance under certain situations. /// public class PrefabPackedIdentifiers : IDeterministicIdentifiers { /// public virtual string GenerateInternalFileName(string name) { return "CAB-" + HashingMethods.Calculate(name); } /// public virtual long SerializationIndexFromObjectIdentifier(ObjectIdentifier objectID) { byte[] assetHash; byte[] objectHash; bool extraArtifact = objectID.filePath.StartsWith("VirtualArtifacts/Extra/", StringComparison.Ordinal); int hashSeed = ScriptableBuildPipeline.fileIDHashSeed; if (extraArtifact && hashSeed != 0) { RawHash fileHash = HashingMethods.CalculateFile(objectID.filePath); assetHash = HashingMethods.Calculate(hashSeed, fileHash).ToBytes(); objectHash = HashingMethods.Calculate(hashSeed, fileHash, objectID.localIdentifierInFile).ToBytes(); } else if (extraArtifact) { RawHash fileHash = HashingMethods.CalculateFile(objectID.filePath); assetHash = fileHash.ToBytes(); objectHash = HashingMethods.Calculate(fileHash, objectID.localIdentifierInFile).ToBytes(); } else if (hashSeed != 0) { assetHash = HashingMethods.Calculate(hashSeed, objectID.guid, objectID.filePath).ToBytes(); objectHash = HashingMethods.Calculate(hashSeed, objectID).ToBytes(); } else { assetHash = HashingMethods.Calculate(objectID.guid, objectID.filePath).ToBytes(); objectHash = HashingMethods.Calculate(objectID).ToBytes(); } int headerSize = ScriptableBuildPipeline.prefabPackedHeaderSize; if (headerSize < 4) { for (int i = 0; i < headerSize; i++) objectHash[i] = assetHash[i]; return BitConverter.ToInt64(objectHash, 0); } else { var assetVal = BitConverter.ToUInt64(assetHash, 0); var objectVal = BitConverter.ToUInt64(objectHash, 0); return (long)((0xFFFFFFFF00000000 & assetVal) | (0x00000000FFFFFFFF & (objectVal ^ assetVal))); } } } }