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。当打包的时候,如果其不依赖于其它包,也不会受到影响。
写了个实现:
打包代码:
///
/// 凡是名字中带_BeDep 的资源,则为被引用资源,加入被引用队列。
/// 其他的prefab 则根据名字打包为assetBundle。默认只打包名字中带有 _AssetB的prefab.
///
[ 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 { 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生成也会和上次不一样。而且是有些会一样,有些不一样。这样会产生大量的不一致问题。