通常在游戏执行过程中,并不希望一次将全部的资源都载入。而是在资源被使用的时候载入,以免占用过多的存储空间。所以我们可能会尽量规划好不同功能的场景,在需要的时候才载入场景并释放掉前个场景中不需要的资源。或是将资源放在Resources文件下,在需要使用的时候用Resources.Load()方法把资源载入。这些者是不错的管理方法,但是当我们游戏中的资源相当多时,输出的程序文件还是会很大。而且如果是时常会更新内容资源的游戏,也会因为过大的资源造成编译输出过长的后果,特别是手机或是网页游戏。最后编译出来的只是一个文件,如果文件非常大,将可能造成下载或启动游戏的不方便;这时候我们可能就要考虑制作AssetBundle。
制作游戏时,将资源和主程序部分分离的话,可以得到某种程度的好处,我们可以让游戏主程序只管理游戏的逻辑部分。当需要某些资源则从外部的AssetBundle载入资源,这样一来,如果有任何游戏更新只是添加或更换资源,并没有变更到程序的逻辑部分。只需要重新打包资源就可以完成更新,而不需要重新编译主程序并重新发布。
例如我们有已上架的iPhone游戏,因为特定节日想把游戏内的图片换成另一种气氛。通常必须要重新输出,然后送审。等到节日过后又想把图片换回原本的,要再次编译新的程序,再送审,一方面送审费时费工,另一方面是从送审到架上游戏更新完成的时间,我们并不能准确掌控;如果事先将资源分离打包成AssetBundle存储在我们自己管理的服务器上,在这种需要换图的时刻,只需要将自己服务器上的AssetBundle更新即可,可以省掉不断送审的麻烦,时间上也更能掌控,另外就是游戏主程序中没有大的资源,主程序会小一点,那么玩家要下载我们的游戏也会更快速一些。
还有就是,我们编译网页游戏时一定会发现,编译出来的只是一个html文件和一个unity3d文件。写过网页的人都知道,网页的运作是浏览器将网页中的文件、图片、音乐、视频等等下载到客户端暂存之后再执行呈现出结果,那么如果我们游戏内容的庞大资源与主程序编在一起的话,那么编译出来的unity3d文件也会很大,此时我们可能要思考一下,我们希望玩家花多久时间完成启动页面再进行游戏呢?也许,Unity的Web Player有办法解决这个问题使玩家不会花太多时间启动页面(传说中流模式),但是正因为网页游戏运作方式是如此,所以当我们在服务器更新时,玩家只要没有重新载入页面,玩到的游戏内容始终是旧版的,此时又要考虑到,如果没有更新游戏逻辑或内容规则的情况下,是否有必要强制玩家中断游戏重新载入页面;如果将资源打包成AssetBundle分离出来,那么unity3d文件这个主程序的部分将会变得比较小,而当有任何资源更新时只需要在服务器端将AssetBundle换掉,玩家不需要重新载入页面,一样能体验到更新后的内容。
以上写了一大堆,主要就是要说明AssetBundle是个很重要又很好用的东西,毕竟在没变更程序或游戏部署的情况下, 没必要去重新编译游戏主程序,以下就来说明如何制作AssetBundle:
首先要使用[Unity插件:自定义菜单命令]的方法自定义菜单命令,使我们能够何时去打包。接下来我们需要能够指定哪些资源进行打包,所以需要使用到Editor class的Selection.GetFiltered(),还有就是要过滤哪些类辊的资源才是我们要的,选择错误略过不处理,最后使用BuildPipeline.BuilAssetBundle()建立AssetBundle即可,以下范例会在Unity项目目录下建立_AssetBundle目录用来存放打包好的AssetBundle,打包的目标为GameObject,
Texture2D, Material三种类别的资源,如果存储文件路径名相同则会先删除旧文件。
[c#]
[MenuItem("Custom Editor/Create AssetBunldes")]
static void ExecCreateAssetBunldes() {
// AssetBundle 的目录名及扩展名
string targetDir = “_AssetBunldes”;
string extensionName = “.assetBundles”;
//取得在 Project 视图中选择的资源(包含子目录中的资源)
Object[] SelectedAsset = Selection.GetFiltered(typeof (Object), SelectionMode.DeepAssets);
//建立存放 AssetBundle 的目录
if(!Directory.Exists(targetDir)) Directory.CreateDirectory(targetDir);
foreach(Object obj in SelectedAsset){
// 资源文件的路径
string sourcePath = AssetDatabase.GetAssetPath(obj);
// AssetBundle 存储路径
string targetPath = targetDir + Path.DirectorySeparatorChar + obj.name + extensionName;
if(File.Exists(targetPath)) File.Delete(targetPath);
if(!(obj is GameObject) && !(obj is Texture2D) && !(obj is Material)) continue;
//建立 AssetBundle
if(BuildPipeline.BuildAssetBundle(obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)){
Debug.Log(obj.name + “建立完成”);
} else {
Debug.Log(obj.name + “建立失败”);
}
}
}
[/c#]
以上是直接将选择的资源打包成AssetBundle,另外,你也可以在打包前,依需求创建好GameObject并添加Component,建立prefab,最后再以Prefab打包成assetBundle,一切看个人如何运用了。
制作好AssetBundle最终目的还是要在游戏中载入,以下用简短范例在游戏画面上显示一个按钮,当按下按钮之后载入类别为GameObject的AsseBundle并利用Instantiate()使其实例化而在场景中产生GameObject。
[c#]
void OnGUI(){
if(GUI.Button(new Rect(5,35,100,25) , “Load GameObject”)) {
StartCoroutine(LoadGameObject());
}
}
private IEnumerator LoadGameObject() {
// AssetBundle 文件路径
string path = string.Format(“file://{0}/../_AssetBunldes/{1}.assetBunldes” , Application.dataPath , “TestGameObject”);
// 载入 AssetBundle
WWW bundle = new WWW(path);
//等待载入完成
yield return bundle;
//实例化 GameObject并等待作业完成
yield return Instantiate(bundle.assetBundle.mainAsset);
//卸载 AssetBundle
bundle.assetBundle.Unload(false);
}
[/c#]
上面代码上AssetBundle文件路径path是以在Editor中实行为例,具体平台要按实际平台来写。因为载入的资源必须要等待载入完成以确保游戏运作正常,在C#中使用yield除了返回类型要是IEnumerator之外,调用时也必须使用StartCoroutine()调用,如果使用Javascript则可直接调用函数。如果AssetBundle已载入过,下次再请求载入将会出现[The asset bundle ‘文件名’ can’t be loaded because another asset bundle
with the same files are already loaded]的错误信息,所以必须在每次载入使用完后,将AssetBundle卸载;另外,要特别注意的是载入AssetBundle到卸载期间可能消耗些微时间,如果连续调用载入同一个AssetBundle,造成在卸载前重复载入也可能出现前面的错误,所以,最好是能定义些变量,记录载入的AssetBundle有哪些,避免重复载入。
打包的脚本:
sing UnityEditor;
public class Test : Editor
{
[MenuItem("Custom Editor/Create AssetBunldes Main")]
static void CreateAssetBunldesMain ()
{
//获取在Project视图中选择的所有游戏对象
Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
//遍历所有的游戏对象
foreach (Object obj in SelectedAsset)
{
//本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径
//StreamingAssets是只读路径,不能写入
//服务器下载:就不需要放在这里,服务器上客户端用www类进行下载。
string targetPath = Application.dataPath + "/StreamingAssets/" + obj.name + ".assetbundle";
if (BuildPipeline.BuildAssetBundle (obj, null, targetPath, BuildAssetBundleOptions.CollectDependencies)) {
Debug.Log(obj.name +"资源打包成功");
}
else
{
Debug.Log(obj.name +"资源打包失败");
}
}
//刷新编辑器
AssetDatabase.Refresh ();
}
[MenuItem("Custom Editor/Create AssetBunldes ALL")]
static void CreateAssetBunldesALL ()
{
Caching.CleanCache ();
string Path = Application.dataPath + "/StreamingAssets/ALL.assetbundle";
Object[] SelectedAsset = Selection.GetFiltered (typeof(Object), SelectionMode.DeepAssets);
foreach (Object obj in SelectedAsset)
{
Debug.Log ("Create AssetBunldes name :" + obj);
}
//这里注意第二个参数就行
if (BuildPipeline.BuildAssetBundle (null, SelectedAsset, Path, BuildAssetBundleOptions.CollectDependencies)) {
AssetDatabase.Refresh ();
} else {
}
}
[MenuItem("Custom Editor/Create Scene")]
static void CreateSceneALL ()
{
//清空一下缓存
Caching.CleanCache();
string Path = Application.dataPath + "/MyScene.unity3d";
string []levels = {"Assets/Level.unity"};
//打包场景
BuildPipeline.BuildPlayer( levels, Path,BuildTarget.WebPlayer, BuildOptions.BuildAdditionalStreamedScenes);
AssetDatabase.Refresh ();
}
}
加载脚本:
private IEnumerator LoadScene()
{
WWW download = WWW.LoadFromCacheOrDownload("http://192.168.1.200/xiaowei/dxw.assetbundle", 1);
yield return download;
//var bundle = download.assetBundle;
//yield return Instantiate(download.assetBundle.mainAsset);
//GameObject obj = (GameObject)download.assetBundle.Load("dxw");
if (download.assetBundle.Contains("dxw"))
{
print(1);
obj = (GameObject)download.assetBundle.Load("dxw");
print(obj);
obj.transform.Rotate(new Vector3(0,0,360));
}
//Application.LoadLevel("Level");
//卸载 AssetBundle
//download.assetBundle.Unload(false);
}
分享到:
相关推荐
Unity3D脚本:Unity3D载入外部视频脚本 Posted on 2013年01月26日 by U3d / Unity3D脚本/插件/被围观 288 次
WWW按需载入Assetbundle1
Unity3D游戏开发FBX模型载入与人物行走动画的播放
雨松MOMO Unity3D 游戏开发系列博文之Unity3D Unity3D 游戏引擎之FBX模型的载入与人物行走动画的播放,欢迎大家下载阅读,哇咔咔~~
Unity3D动态加载模型贴图方法2
Unity3d 用键盘控制运行速度和重新载入当前场景的脚本
通过UniFBX插件完成的一个模型加载案例 1 unity3d的版本要在5.5以上版本 2 使用语言c# 3 自制案例路径在 “CSUE/load2.unity” 4 使用时应对自身需求做出更改,本案例只做参考学习
在游戏中经常需要动态地载入一些数据。例如让玩家定制角色外貌时,需要从数据文件读取各种身体部位的信息;或者玩家访问NPC购买装备时,需要从数据文件读取装备信息等等。为了减少游戏程序的大小,我们往往采用最...
Unity3D 场景加载过渡资源 异步加载场景资源 附带自然的加载画面 公司项目demo 亲测好用 软件载入中界面 pc和安卓都支持
unity宝石三消手机游戏完整源码,游戏中包含画面载入、关卡选择、数据加载、声音、精灵控制、动画,游戏画面超棒,出现元素很多, UI可以更换定制,好玩到根本停不下来! 亲爱的同学们可以下载亲自体验一下~ 开发...
这个比较实用的,可以动态载入多种模型,特别是FBX模型,在创建场景时候很好用,不过这个是试用版本,贴图会有问题,如果要更好的还是推荐买正版
Playmaker 1.1现在在Unity Asset Store上出售,售价为100美元。 关于Hutong Games Hutong Games由Alex Chouls和e.Ko在2010年创办,致力于开发各种创新的互动娱乐。在这一过程中,我们开发了能够让创意人士使用的工具...
游戏截图截图 ... 原名是:Match3Jewel Full 298 Levels(宝石第3...包含画面载入、关卡选择、数据加载、声音、精灵控制、动画,用unity4.6或unity5打开,游戏画面超棒,出现元素很多,集成了Admob和Google Analytics ……
易语言制作的软件 全兴动画 载入程序是阿萨德是
webgl载入模型webgl载入模型webgl载入模型 webgl载入模型webgl载入模型webgl载入模型
WIN7用虚拟光驱 镜像制作 镜像载入
//背景色pt+='<paramname="backgroundcolor"value="000000"/>';//进度条图片(格式必须为PNG)pt += '
Unity 工具之 UniWebView 内嵌网页/浏览器到应用中,并且根据UGUI大小放置(简单适配UGUI) 注意:UniWebView 使用版本为 UniWebView 3.7.0 UniWebView 包含一组 C# 的高层级 API,它对 iOS 和 Android 平台的本机 ...
c#中采用directX9.0载入3D模型,实现需要下载并且安装DirectX9.0SDK,如果不能运行的话,就在工程中手动引用DirectX.dll,DirectX3D.dll,DirectX3DX.dll
常常使用 Spine 来制作一些动画,这个插件是用来让unity可以播放spine制作的动画