Unity3d-AssetBundle基本格式分析

来源:互联网 发布:基尼系数数据 编辑:程序博客网 时间:2024/04/28 15:50

参考disunity 和云风的分析写的C#版本的 AssetBundle基本格式分析工具:https://github.com/chenanbao/AssetBundleReader


AssertBundle文件头: 

        public void Read(ByteArray bs)        {            signature = bs.ReadStringNull();            streamVersion = bs.ReadInt();            unityVersion = bs.ReadStringNull();            unityRevision = bs.ReadStringNull();            minimumStreamedBytes = bs.ReadInt();            headerSize = bs.ReadUInt();            numberOfLevelsToDownload = bs.ReadInt();            int numberOfLevels = bs.ReadInt();            for (int i = 0; i < numberOfLevels; i++)            {                levelByteEnd.Add(new LevelInfo() { PackSize = bs.ReadUInt(), UncompressedSize = bs.ReadUInt() });            }            if (streamVersion >= 2)            {                completeFileSize = bs.ReadUInt();            }            if (streamVersion >= 3)            {                dataHeaderSize = bs.ReadUInt();            }            bs.ReadByte();        }

AssetBundle具体数据使用LZMA压缩(开源库:http://www.7-zip.org/sdk.html):

                SevenZip.Compression.LZMA.Decoder coder = new SevenZip.Compression.LZMA.Decoder();                uint length = (uint) (fs.Length - header.GetHeaderSize());                byte[] inBytes = new byte[length];                inData.ReadBytes(inBytes, 0, length);                MemoryStream input = new MemoryStream(inBytes);                MemoryStream output = new MemoryStream();                // Read the decoder properties                byte[] properties = new byte[5];                input.Read(properties, 0, 5);                // Read in the decompress file size.                byte[] fileLengthBytes = new byte[8];                input.Read(fileLengthBytes, 0, 8);                long fileLength = BitConverter.ToInt64(fileLengthBytes, 0);                coder.SetDecoderProperties(properties);                coder.Code(input, output, input.Length, fileLength, null);                output.Position = 0;

解压后的数据格式如下,一般只包含一个Asset:

                        uint files = inData.ReadUInt();            Debug.Log(files);            for (int i = 0; i < files; i++)            {                AssetBundleEntryInfo entryInfo = new AssetBundleEntryInfo();                entryInfo.Read(inData);                entryInfos.Add(entryInfo);                Debug.Log("AssetBundleEntryInfo");                inData.Postion = (int)entryInfo.GetOffset();                AssetHeader assetHeader = new AssetHeader();                assetHeader.Read(inData);                Debug.Log("AssetHeader");                MetadataInfo metadataInfo = new MetadataInfo();                metadataInfo.Read(inData, assetHeader);                Debug.Log("MetadataInfo");                //后面的都是小端读取                inData.IsBigEndian = false;                ObjectInfoTable objectInfoTable = new ObjectInfoTable();                objectInfoTable.Read(inData);                Debug.Log("ObjectInfoTable");                FileIdentifierTable fileIdentifierTable = new FileIdentifierTable();                fileIdentifierTable.Read(inData, assetHeader);                Debug.Log("FileIdentifierTable");            }

其中ObjectInfo的classID含义可参见:http://docs.unity3d.com/Documentation/Manual/ClassIDReference.html



1 0
原创粉丝点击