【小松教你手游开发】【unity系统模块开发】Unity Assetbundle打包笔记

*最近项目更新了Unity5.5.2,顺便更新了项目的ui打包,也更新一下这边的笔记

首先打包分为两部分,一部分是打包成Assetbundle包,一部分是从Assetbundle包解包出来成为可用的资源。

首先说第一部分 打包

所有资源都可以打包,甚至不是资源(一些数据)也可以打包,只要你需要。

打包出来的东西都可以直接用,一个字体,一个Texture,一个Prefab,一个场景,都是一打出来成Assetbundle包就可以直接用,但是为什么大家还是要各自开发自己的打包流程呢?

最重要的原因就是,如果不论什么都直接打包,比如你在开发两个UI界面,这两个UI界面都用到同一个Texture,同一个Font,而你又各自打包两个Prefab,这时在两个bundle包里就都会包含这个Texture和这个Font,也就是它重复存在占用了多一份内存。

所以为了解决这种问题,基本上每个项目都会在打包的时候把Texture,Atlas,Font等用到的相同资源剥离,记录,之后再打包,等到用的时候再加载回来。

这就是每个项目自己的打包流程主要的开发工作。

而现在的unity版本(我们项目用的是unity5.3.5f)提供了剥离方法,以前的unity版本需要自己剥离。等下在下面讲打包的时候两种都会讲到。(虽然你只需要用一种,为了详细 就两种都讲)

接下来讲我们项目的打包流程。

首先打包一般的Texture,Atlas都比较简单,有两个是比较特殊需要独立开发的情况

1.打包Panel(UI界面)

2.打包Scene(游戏场景)

先来说一下打包Panel

一个UI界面里你会用到很多图片,很多字体,不管是Atlas或者Texture你都需要把这些剥离开来。

打包Panel我们使用自己的剥离方式。

假设现在有一个BattleUI.Prefab

下面是打包步骤。

1.清理数据,建立文件夹(存放不同类型的文件,如Texture、Atlas)

2.PrefabUtils.Instantiate实例化这个Prefab。

3.获取这个实例化后的Prefab下的所有动态组件(这个看不同项目)

4.获取这个GameObject上挂的所有NGUI脚本。(如果有动态组件,每个动态组件也要遍历所有NGUI脚本)

5.把NGUI脚本复制下来用一个类存放并挂载这个GameObject上,如:

Public Class PRefabHierarchyInfo:MonoBehavior
{
 public Transform[] transforms;
 public UILabel[] uilabels;
 public UIPanel[] uipanels;
 public UISprite[] uisprites;
}  

6.把引用到的Texture、Atlas、Font、Panel(界面)记录下来
7.把原本NGUI脚本女上引用到的Texture.Atlas全部置空

*步骤3-7的目的在于,把这个界面或者多个界面用到的Texutre、Atlas信息来出来,统一处理,不然直接打包就会一个资源存在多份

8.把步骤6找到的所有资源打包BuildPipeline.Build(如果是Atlas不用CreateGameObject,其他要用PrefabUtility.CreatePrefab())(这里还可以根据不同平台不同要求设置Atlas属性等)
9.打包Panel

*原本想写在这里,发现东西太多另起一篇文章来记录

*下面是更新新的打包ui方式链接

http://blog.csdn.net/chrisfxs/article/details/60136875

接下来是打包Scene

打包场景的目的是在于,把场景中的所有动态组件抽出来,把所有用到的Material和Shader分离并单独打包

而我们打包场景的方式选择现在unity的自动剥离方法(改AssetBundle名即会独自打包(自动分离)(用AssetImporter类,改assetImporter.assetBundleName))

下面是打包步骤:

1.清除所有AssetBundleName

2.找到项目里所有需要打包的Scene

3.找到每个Scene下的所有需要打包和需要独立打包的东西(如Material、Shader)

4.获取所有需要打包的物件的资源地址,一个场景写一个Config文件并存放到里面

5.改每个scene的AssetBundleName

6.改每个需要单独打包(剥离)的物件的AssetBundleName(如Shader、Texture、Material、GameObject(动态组件))

7.BuildPipeline.BuildAssetBundle()

打包系统会把重新改了AssetBundleName的物件剥离并独自打包,剩余的统一打成一个场景包

这样就基本完成打包工作。

接下来是解包。

加载Panel

1.加载AssetBundle(AssetBundle.LoadFromFileAsync(path))

2.放入内存

3.在打开界面的时候实例化界面类,把数据还原。如,CDialog为界面类,CPanel为这个界面的数据类,把之前打包流程6-7记录的Atlas和Font等数据重新赋值回去

加载Scene场景

1.加载Config

2.加载场景Scene到内存

3.移步实例化Scene

4.加载Shader,Texture

5.加载Material

*4.5这两个顺序不能,因为之前打包有依赖关系,加载Material之前要先加载Shader、Texture

6.加载动态组件(根据之前的Config重新摆放物体等信息)

...

原文地址:http://blog.51cto.com/13638120/2084959

时间: 2025-01-06 18:10:40

【小松教你手游开发】【unity系统模块开发】Unity Assetbundle打包笔记的相关文章

【小松教你手游开发】【unity实用技能】角色头部跟随镜头旋转

这个在端游上比较场景,在角色展示的时候,当摄像头在角色身边上下左右旋转时,角色头部跟随镜头旋转.如天涯明月刀等. 这个在手游上比较少见,不过实现也没什么区别. 首先一般情况下,找到模型的头部节点,直接用lookAt指向camera就可以了,不过一般需求不会这么简单. 比如说,超过头部扭动极限,头部需要插值回到原始点:当镜头从外部回到极限内,需要插值回来.这时候lookat就没法使用. 更有情况,头部本身坐标系不在世界坐标轴上, 可能旋转了90多或者输出的prefab就是歪的等等,这些情况都没办法

【小松教你手游开发】【unity实用技能】根据上一个GameObject坐标生成的tips界面

开发游戏,特别是mmo手游的时候经常需要开发的一个需求是,点击某个装备,在它附近的位置生成一个tips界面,介绍装备功能和各种信息. 像上面红色框框里的这个. 这个主要的问题是 根据点击的GameObject对应生成这个详情界面时,详情界面位置需要合理摆放(不能显示不到,不能遮挡等) 基本的思路是, 首先找到GameObject的position, 把手机屏幕大概分成四个象限,知道这个GameObject大概在这个屏幕的哪个象限(左上,左下,右上,右下) 根据象限来判断详情界面应该在GameOb

【小松教你手游开发】【unity系统模块开发】热更

现在的手游项目如果没个热更新迭代根本跟不上, 特别是像我们项目做mmo的更是需要经常改动代码. 而现在的项目一般会选择用lua的方式实现热更新 不过我们项目由于历史原因没有使用,用的是另外一种方案 在项目里的所有GameObject都不挂脚本(NGUI脚本就通过代码的方式挂上),自己写的脚本都不继承Mono并打成dll,然后通过一个启动脚本去打开这些dll. 不过这样就有个问题,ios不能热更... 不管怎么样,先来讲讲这种方案要怎么做. 首先有两部分,一部分是打包,一部分是解包. 而包又分为资

【小松教你手游开发】【系统模块开发】unity 数据储存到本地为二进制文件(聊天记录本地储存)

unity游戏开发中有很多需要把数据储存到本地,官方有好几个方式可以使用,下面简单介绍一下. 一.Stream::Write,Stream::WriteLine 这个方法是打开数据流就开始写字符串,可以指定长度写,也可以一行一行的写.具体参考http://blog.csdn.net/dingxiaowei2013/article/details/19084859和雨松大神的http://www.xuanyusong.com/archives/1069 这种方法最简单,一行一行的写,一行一行的读,

【小松教你手游开发】【unity系统模块开发】unity网络层读写

在unity做强联网游戏的时候一般会选择用tcp来做通信(据说有一种udp的传输具有更高的效率),而接收信息的方法上一般会选择新建一个线程循环读取. 今天在我们项目上看到另外的一种方法.这里记录一下. 首先建立tcp连接 #using System.Net.Sockets; TcpClient tcpClient = new TcpClient(); tcpClient .BeginConnect(address,port,new AsyncCallback(this.OnConnect),re

【小松教你手游开发】【unity实用技能】拓展函数(给系统代码添加可直接使用的接口)

拓展函数的意思是给一些没有源码的脚本添加上你自己写的接口并可以直接调用. using UnityEngine; using System.Collections; namespace ExtensionMethods { public static class MyExtensions { public static void SetLocalPositionX(this Transform transform, float x) { Vector3 newPosition = new Vect

【小松教你手游开发】【unity系统模块开发】Unity5.5.2UI打包AssetBundle

之前已经有几篇文章写打包AssetBundle,但毕竟没有实际在项目中写过都写的比较浅. 刚好最近项目更新Unity5.5.2就顺便由我来更新ui打包流程 这里就把这次的经验写一下 这里还是稍微解释一下打包的基本目的: 打包ui就是把你做的界面打包出来成assetbundle包,讲道理你就把每个界面打成bundle包在游戏中你就可以直接加载来用,但是这样子的话你的每个bundle包就会非常的大,为什么呢,是因为这样子每个界面的bundle包里都包含这个界面用到的字体,贴图atlas,textur

【小松教你手游开发】【系统模块开发】做一个3d旋转菜单

在unity做一个3d旋转菜单,像乱斗西游2的这种: 暂时有两种方法可以实现: 一.当做是2d界面,通过定义几个固定点的坐标.大小.透明度,还有每个点的panel depth大小,把数据存储下来,在手机滑动的过程中计算滑动划过的距离和这个panel大小的比值,乘以两个点之间的距离,获得坐标点移动的距离,通过改变x轴改变位置,同理改变大小和透明度. 这个方法我自己做2d游戏的时候实现过,做起来比较简单,没有什么可拓展性可言,并且会有很多限制,比如拖动过程中很难转变方向.要自己实现运动中的弹性(这里

【小松教你手游开发】【unity实用技能】InvalidOperationException: out of sync

在unity开发中出现这个bug. 在网上查了下是在迭代器中直接修改引起的.c#是不允许你在迭代器中直接修改. 改了一下确实解决. 原本是这样 [csharp] view plain copy public void Run() { foreach (var item in timerDict) { if (null != item.Value) { item.Value.Run(); } } } 改成这样: [csharp] view plain copy public void Run()