Unity BuildPipeline BuildAssetBundleOptions
https://blog.csdn.net/zhjzhjxzhl/article/details/79743299
BuildAssetBundleOptions
Description
Asset Bundle building options.
See Also: BuildPipeline.BuildAssetBundle.
Variables
CollectDependencies Includes all dependencies. 包括所有的引用,会循环查找
CompleteAssets Forces inclusion of the entire asset. 包括一起导入的内容
DisableWriteTypeTree Do not include type information within the AssetBundle.
DeterministicAssetBundle Builds an asset bundle using a hash for the id of the object stored in the asset bundle.
UncompressedAssetBundle Don't compress the data when creating the asset bundle. 不压缩
BuildPipelineNamespace: UnityEditor
Description
Lets you programmatically build players or AssetBundles which can be loaded from the web.
Static Variables
isBuildingPlayer Is a player currently being built?
Static Functions
BuildAssetBundle Builds an asset bundle (Unity Pro only).
BuildAssetBundleExplicitAssetNames Builds an asset bundle, with custom names for the assets (Unity Pro only).
BuildPlayer Builds a player (Unity Pro only).
BuildStreamedSceneAssetBundle Builds one or more scenes and all their dependencies into a compressed asset bundle.
PopAssetDependencies Lets you manage cross-references and dependencies between different asset bundles and player builds.
PushAssetDependencies Lets you manage cross-references and dependencies between different asset bundles and player builds.
当使用依赖打包时。在对被依赖的包使用buildAssetBundle之前,需要先调用pushAssetDependencies。这样就加入的被依赖树。
如果有其他Asset依赖它,就不会重复打包这个。如果其他包不依赖这个,也不会有什么关系。依赖结束后,必须使用popAssetDenpendencies
弹出依赖。
string path = getpath();
BuildPipeline.PushAssetDependencies();//下面这个包将会被别的包依赖
var options = BuildAssetBundleOptions .CollectDependencies;
BuildPipeline.BuildAssetBundle(AssetDatabase .LoadMainAssetAtPath("Assets/NGUI/Examples/Atlases/Wooden/Wooden Atlas.prefab"),null ,path+"WoodenAtlas_prefab.assetBundle",options);//被依赖的包
BuildPipeline.PushAssetDependencies();//下面这个包将会被别的依赖,其实这段程序中没有包依赖它,但是不会产生什么影响
BuildPipeline.BuildAssetBundle(AssetDatabase .LoadMainAssetAtPath("Assets/NGUI/Examples/Atlases/Wooden/Test Atlas.prefab"), null , path + "TestAtlas_prefab.assetBundle", options);//被依赖的包
//下面这个包依赖于上面的包(Wooden Atlas.prefab),并不依赖于 Test Atlas.prefab
BuildPipeline.BuildAssetBundle(AssetDatabase .LoadMainAssetAtPath("Assets/TestAssetBundleDepen/Sprite.prefab"), null , path + "SpriteDependentWoodAtlas.assetBundle", options);
// 弹出依赖,结束打包过程。
BuildPipeline.PopAssetDependencies();
BuildPipeline.PopAssetDependencies();
BuildPipeline.BuildAssetBundle(AssetDatabase .LoadMainAssetAtPath("Assets/TestAssetBundleDepen/Sprite.prefab"), null , path + "SpriteUnDependentWoodAtlas.assetBundle", options);
在使用WWW.LoadFromCacheOrDownload时,如果有依赖关系,则必须先将依赖包全部加载入内存。
AssetBundle ab;
WWW ye1;
//下加载被依赖的包,一般是基础库。比如大家都会引用的Atlas等
ye = WWW.LoadFromCacheOrDownload(@"file://C:/Users/MUHE/Documents/New Unity NGUITestFrameWork/export/windows/WoodenAtlas_prefab.assetBundle", 2);
yield return ye;
ab = ye.assetBundle;
ye1 = ye;
ye = null;
if (ye == null ) {
Debug.Log("start" );
//加载依赖包,一般可能是单个面板
ye = WWW.LoadFromCacheOrDownload(@"file://C:/Users/MUHE/Documents/New Unity NGUITestFrameWork/export/windows/SpriteDependentWoodAtlas.assetBundle", 2);
}
yield return ye;
GameObject go = (GameObject )Instantiate (ye.assetBundle.mainAsset);
go.transform.position = new Vector3 ();
ab.Unload( false);
ye1.Dispose();
上例子中SpriteDependentWoodAtlas依赖于WoodenAtlas_prefab。
实际使用过程中,如果需要有依赖包和使用包。最好在命名的时候都先命好(入:被依赖的包A名字为A_BeDependent.***,其它包则命名无要求)。这样的话,自动化打包工具,就可以很方便的给所有被依赖的包提前加入pushAssetDependencies。当打包的时候,如果其不依赖于其它包,也不会受到影响。
写了个实现:
打包代码:
/// <summary>
/// 凡是名字中带_BeDep 的资源,则为被引用资源,加入被引用队列。
/// 其他的prefab 则根据名字打包为assetBundle。默认只打包名字中带有 _AssetB的prefab.
/// </summary>
[ MenuItem("GameTools/Resource/根据被引用和引用的顺序生成AssetBundle" )]
public static void buildAssetBundleWithDependentAndUnDependentOrder()
{
BuildAssetBundleOptions options = BuildAssetBundleOptions .CollectDependencies;
BuildTarget target = BuildTarget .StandaloneWindows;
string[] assets = AssetDatabase .GetAllAssetPaths();
string path = getpath();
int denpendenciesTimes = 0;
//将所有公用库添加进文件里,游戏中提前加载
StreamWriter sw= new StreamWriter( target.ToString()+BEDENPENDENT + ".txt");
//第一遍,添加被引用的资源
foreach (string asset in assets)
{
if (asset.Contains(PREFAB_EXT) && asset.Contains(BEDENPENDENT))
{
string name = asset.Substring(asset.LastIndexOf("/") + 1);
//后缀
string nameExt = name.Substring(name.LastIndexOf(".") + 1);
string assetPath = asset.Substring(0, asset.LastIndexOf("/")+1);
string newPath = path + assetPath;
if (!Directory .Exists(newPath))
{
Directory.CreateDirectory(newPath);
}
name = name.Substring(0, name.Length - (nameExt.Length+1));
UnityEngine. Object pre = AssetDatabase .LoadMainAssetAtPath(asset);
BuildPipeline.PushAssetDependencies();
denpendenciesTimes++;
string newFileName = newPath + name+"_"+nameExt + ".assetBundle";
BuildPipeline.BuildAssetBundle(pre, null ,newFileName,options,target);
sw.WriteLine(newFileName);
}
}
sw.Close();
foreach (string asset in assets)
{
if(asset.Contains(PREFAB_EXT) && !asset.Contains(BEDENPENDENT) && asset.Contains(IS_ASSET_BUNDLE))
{
string name = asset.Substring(asset.LastIndexOf("/") + 1);
//后缀
string nameExt = name.Substring(name.LastIndexOf(".") + 1);
name = name.Substring(0, name.Length - (nameExt.Length + 1));
string assetPath = asset.Substring(0, asset.LastIndexOf("/")+1);
string newPath = path + assetPath;
if (!Directory .Exists(newPath))
{
Directory.CreateDirectory(newPath);
}
UnityEngine. Object pre = AssetDatabase .LoadMainAssetAtPath(asset);
string newFileName = newPath + name+"_"+nameExt + ".assetBundle";
BuildPipeline.BuildAssetBundle(pre, null ,newFileName, options,target);
}
}
for(int i = 0;i<denpendenciesTimes;i++)
{
BuildPipeline.PopAssetDependencies();
}
}
使用代码:
//测试序列依赖库
const string resRoot = "file://C:/Users/MUHE/Documents/New Unity NGUITestFrameWork/";
//依赖配置文件
const string depfile = "StandaloneWindows_BeDep.txt";
//真实环境下可能从网络或者别的地方加载
System.IO. StreamReader sr = new System.IO.StreamReader(depfile);
Debug.Log("start time -----------------------------" + Time.time);
QueueLoader ql = QueueLoader .createLoader((QueueLoader qlfin) =>
{
Debug.Log("all finished=================" + Time.time);
Update1();
}, ( float progress) =>
{
Debug.Log("current progress is " + progress * 100);
}, 5);
string bedep = sr.ReadLine();
while (bedep != null )
{
ql.addOneRequest( new LoadRequest (resRoot + bedep, null, null, null, null, LoadRequest.LOAD_DATA_TYPE .RESOURCE));
bedep = sr.ReadLine();
}
ql.start();
void Update1 () {
if (ye == null )
{
StartCoroutine(startWWW());
//Debug.Log("Update thread id is " + System.Threading.Thread.CurrentThread.ManagedThreadId.ToString());
}}
IEnumerator startWWW()
{
if (ye == null ) {
Debug.Log("start" );
ye = WWW.LoadFromCacheOrDownload(@"file://C:/Users/MUHE/Documents/New Unity NGUITestFrameWork/export/windows/Assets/TestAssetBundleDepen/Sprite_AssetB_prefab.assetBundle", 2);
}
yield return ye;
GameObject go = (GameObject )Instantiate (ye.assetBundle.mainAsset);
go.transform.position = new Vector3 ();
}
依赖打包的过程中,如果不使用BuildAssetBundleOptions .DeterministicAssetBundle,则会出现。如果a依赖b。a改变,而b不发生变化的时候,ab都需要更新。
否则的话,a也会显示不正确。如果使用BuildAssetBundleOptions .DeterministicAssetBundle,则不会有这个问题。但是有可能出现hash冲突。具体可以看这个属性的说明。
BuildAssetBundleOptions .DeterministicAssetBundle,如果不加入这个参数,即使prefab不改变任何东西,每次使用BuildPipeline.BuildAssetBundle生成也会和上次不一样。而且是有些会一样,有些不一样。这样会产生大量的不一致问题。
————————————————
版权声明:本文为CSDN博主「zhjzhjxzhl」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhjzhjxzhl/article/details/79743299