核心入口:
在AssetbundleBuilder中的BuildCustomAssetBundle。他接受的参数包括主资源,对象,覆盖路径,目标保存路径,平台,平台参数等。
大致实现步骤:
1.重新打atlas
RebuildAtlasCacheIfNeeded。这里比较多内容,具体实现以后再讲
2.检查资源是否正常
取出所有正常的资源,BuildInitialObjectSet
3.创建assetBundle类,在后面会用列表记录他。
创建assetBundle他会有个NEW_OBJECT这个方法,他是创建一个对象的并且他会给每个对象都赋值一个唯一的instancedid。则个id是从-10不断的减2得到的。
4.组织成BuildAsset
这里包括有instanceid,还有获取到的classid,他还会获取一个提前加载的顺序preloadSortIndex,通过CalculateSortIndex计算优先级,比如像monobehaviour的优先级是1000000。preloadSortIndex是在AssignTemporaryLocalIdentifierInFileForAssets中用来对BuildAsset排序。因为打包时,BuildPlayer会执行DoBuildPlayer,执行的BuildPlayerData,会执行CompileGameResourceManagerDependencies会执行。AssignTemporaryLocalIdentifierInFileForAssets来做排序。这样可以按照顺序来处理依赖对象。
注意:ClassIDs.h这里有对unity中的类型分号classid。用来判断类型如asset->mainRepresentation.classID == ClassID(GameObject);
5.收集依赖CollectDependencies
如果是pptr也就是unity的指针就会加入到m_IncludedObjects中。
6.收集instanceid和资源
他是从m_IncludedObjects中的对象获取相关的instanceid,并且会手机相关的guid到m_IncludedAssets。通过guid能够获取回原本的asset结构体。
7.如果需要包含已经完成的额资源
则加入AddInstanceIDsOfCompleteAssets。如果选择可以接受让之前存在的内容进当前ab包,则会收集所有已经在其他ab包的数据到当前ab包。
他这里会判断main的资源和依赖的资源是否都是prefab也就是gameobject的class类型,如果是则跳过,他的意思是只需要资源中的根游戏对象。不是所有的子游戏对象!
如果不是则收集在BuildSerialization的m_IDs中。
8.检查是否有丢失的资源VerifyComponentsAndChildTransformsArePresent
他会遍历所有的instance(m_IncludedObjectIDs)如果有Component是不存在m_IncludedObjectIDs中的就算是丢失了。然后同样去找他的transform和子transform,如果有不在m_IncludedObjectIDs中的就算是丢失了。
9.把丢失的texture重新加入到ab打包中AddMissingSpriteTextures
他会找到m_IncludedObjectIDs中所有属于Sprite的对象,然后拿他的贴图指针,放到textures中,并在m_IncludedObjectIDs中插入这个指针区间。
10.为我们收集的所有实例ID添加BuildAssets
AddBuildAssets。用BuildAsset来描述m_IncludedObjectIDs里的数据。
11.为所有assets添加assetinfos
CreateAllAssetInfos。AddPreloadTableEntries中执行插入要加载的指针到m_PreloadTable。
前面这几步主要都是针对instanceid,guid等组织成希望的数据结构。
12.确定资源类型的标记ComputeObjectUsage
这里会用于标记出用到的meshcollider,renderer,terraindata,proceduralmaterial,particlesystem,particlesystemrenderer。最终标记放在m_BuildAssets中。而且之后的操作都跟m_BuildAssets有关。
13.AssignTemporaryLocalIdentifierInFileForAssets中做排序SortPreloadAssetsByFileID
跟第四部中的排序一致,拿到第四部的排序顺序在这里排。
14.如果关闭了tyeptree
这个是一个类型检查,如果关闭,会对unity版本切换后的兼容性有影响。他要跟脚本的关联CreateScriptCompatibilityInfo。把对应的脚本放到m_ScriptCompatibility队列中,然后把classuid和相应的hash插入到typeTreeHashes,最终拷贝到m_ClassCompatibility中。这个是额外的一步。如果执行这一步,ab包会变小,因为没保存结构体而是保存对应的数值,所以跨版本后如果结构体变了,就可能数值对应不上了,就会报错。
15.写入共享资源WriteSharedAssetFile
也就是把m_BuildAssets写入到我们确定的路径m_BuildAssets中。这个其实是执行落地的一步了,把ab包输出到目录下。
16.之后就是文件大小的输出和检查临时资源信息VerifyAllAssetsHaveAssignedTemporaryLocalIdentifierInFile