AssetBundle
无论是模型资源还是UI资源,最好是先把他们放在Prefab中,然后在做成Assetbundle
Prefab可以被看做是对scene(场景)中game object(游戏物体)的描述文件,可以被储存在Assets文件夹内,以方便在其他scene中重复利用。Prefab实际上并不包含任何模型、贴图等真正的素材文件,只是一个虚拟的“参考”。
我们可以把prefab当做一种特殊的“资源素材”,在场景中引用prefab,相当于按照这个prefab所描述的规范引用其涉及到的“真实素材”。如果我们不小心删除掉了这些“真实素材”,那么prefab就失去了作用。
第一步 先选中一个预制体(Prefab) 在Inspector 面板的最下方找到"AssetBundle"进行设置
有可能点击Inspector面板发现没有 如这样:
这个action是预制体的名字 点击它,就会展开
2.编辑添加assetbundle标签
点击输入框 默认是"none" 这里有两个"None"两个输入框分别代表名称和后缀 可以根据自己的工程分类进行命名
-->new :输入编辑第一个名称入:add 第二个名称:androidload
打包出来的文件有两个: .manifest是配置文件
add.androidload
add.androidload.manifest
也可以以文件夹的方式命名
-->new :输入编辑第一个名称入:prefabs/add 第二个名称:androidload
接下来通过脚本在菜单栏中生成一个执行命令
using UnityEditor;
using System.IO;
using UnityEngine;
public class CreateAssetBundles
{
[MenuItem("Assets/Build AssetBundles")]
static void BuildAllAssetBundles()
{
//文件存储位置
string assetBundleDirectory = "Assets/AssetBundles";
if (!Directory.Exists(assetBundleDirectory))
{
Directory.CreateDirectory(assetBundleDirectory);
}
//BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.Android);
string targetPath = Application.dataPath + "/AssetBundles";
// string targetPath = Application.dataPath + "/StreamingAssets";//android assets文件夹
BuildPipeline.BuildAssetBundles(targetPath,BuildAssetBundleOptions.ChunkBasedCompression,BuildTarget.Android);
}
}
需要说明参数:
string targetPath ="Assets/StreamingAssets";// unity文件夹Assets/StreamingAssets会打包在android assets文件夹
>>本地测试:建议最后将Assetbundle放在StreamingAssets文件夹下,如果没有就创建一个,因为移动平台下只能读取这个路径 string targetPath = Application.dataPath + "/StreamingAssets";//打包后文件将会在android assets文件夹中
- BuildAssetBundleOptions.None:此捆绑包选项使用 LZMA 格式压缩,这是一个压缩的 LZMA 序列化数据文件流。LZMA 压缩要求在使用捆绑包之前对整个捆绑包进行解压缩。此压缩使文件大小尽可能小,但由于需要解压缩,加载时间略长。值得注意的是,在使用此 BuildAssetBundleOptions 时,为了使用捆绑包中的任何资源,必须首先解压缩整个捆绑包。
解压缩捆绑包后,将使用 LZ4 压缩技术在磁盘上重新压缩捆绑包,这不需要在使用捆绑包中的资源之前解压缩整个捆绑包。最好在包含资源时使用,这样,使用捆绑包中的一个资源意味着将加载所有资源。这种捆绑包的一些用例是打包角色或场景的所有资源。
由于文件较小,建议仅从异地主机初次下载 AssetBundle 时才使用 LZMA 压缩。通过 UnityWebRequestAssetBundle 加载的 LZMA 压缩格式 Asset Bundle 会自动重新压缩为 LZ4 压缩格式并缓存在本地文件系统上。如果通过其他方式下载并存储捆绑包,则可以使用 AssetBundle.RecompressAssetBundleAsync API 对其进行重新压缩。 - BuildAssetBundleOptions.UncompressedAssetBundle:此捆绑包选项采用使数据完全未压缩的方式构建捆绑包。未压缩的缺点是文件下载大小增大。但是,下载后的加载时间会快得多。
- BuildAssetBundleOptions.ChunkBasedCompression:此捆绑包选项使用称为 LZ4 的压缩方法,因此压缩文件大小比 LZMA 更大,但不像 LZMA 那样需要解压缩整个包才能使用捆绑包。LZ4 使用基于块的算法,允许按段或“块”加载 AssetBundle。解压缩单个块即可使用包含的资源,即使 AssetBundle 的其他块未解压缩也不影响。
- 使用 ChunkBasedCompression 时的加载时间与未压缩捆绑包大致相当,额外的优势是减小了占用的磁盘大小。
BuildTarget 本工程开发平台是android所以:,BuildTarget.Android
BuildTarget.Standalone:这里我们告诉构建管线,我们要将这些 AssetBundle 用于哪些目标平台。可以在关于 BuildTarget 的脚本 API 参考中找到可用显式构建目标的列表。但是,如果不想在构建目标中进行硬编码,请充分利用 EditorUserBuildSettings.activeBuildTarget,它将自动找到当前设置的目标构建平台,并根据该目标构建 AssetBundle。
一旦正确设置构建脚本,最后便可以开始构建资源包了。如果是按照上面的脚本示例进行的操作,请单击 Assets > Build AssetBundles 以开始该过程。
现在已经成功构建了 AssetBundle,您可能会注意到 AssetBundles 目录包含的文件数量超出了最初的预期。确切地说,是多出了 2*(n+1) 个文件。让我们花点时间详细了解一下 BuildPipeline.BuildAssetBundles 产生的结果。
对于在编辑器中指定的每个 AssetBundle,可以看到一个具有 AssetBundle 名称+“.manifest”的文件。
读取:
//加载Android资源 Assets/StreamingAssets
LoadABPackage("/prefabs/add.androidload", "add");
void LoadABPackage(string path,string prefabs) {//
读取apk包文件时 需要 "!assets"+path 需要加 "!" 生成路径为: Application.dataPath + "/StreamingAssets";时可以调用此方式加载
AssetBundle ab1 = AssetBundle.LoadFromFile(Application.dataPath + "!assets"+path);
//资源文件放在文件下 /data/data/包名/files 生成路径: Application.dataPath + "/AssetBundles";
AssetBundle ab1 = AssetBundle.LoadFromFile(Application.persistentDataPath + "/assets"+path);
GameObject goPrefab = ab1.LoadAsset<GameObject>(prefabs);
GameObject luzhang = GameObject.Instantiate<GameObject>(goPrefab);
}
## Unity中的Path对应各平台中的Path
**OS:**
Application.dataPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data
Application.streamingAssetsPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/xxx.app/Data/Raw
Application.persistentDataPath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Documents
Application.temporaryCachePath : Application/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/Library/Caches
**Android:**
Application.dataPath : /data/app/xxx.xxx.xxx.apk
Application.streamingAssetsPath : jar:file:///data/app/xxx.xxx.xxx.apk/!/assets
Application.persistentDataPath : /data/data/xxx.xxx.xxx/files
Application.temporaryCachePath : /data/data/xxx.xxx.xxx/cache
steamingAssetsPath 打包到apk
persistentDataPath
**Windows Web Player:**
Application.dataPath : file:///D:/MyGame/WebPlayer (即导包后保存的文件夹,html文件所在文件夹)
Application.streamingAssetsPath :
Application.persistentDataPath :
Application.temporaryCachePath :
打包到
using UnityEditor;
using System.IO;
using UnityEngine;
public class CreateAssetBundles
[MenuItem("Assets/Build AssetBundles")]
static void BuildAllAssetBundles()
{
// 设置生成文件保存位置
string assetBundleDirectory = "Assets/AssetBundles";
if (!Directory.Exists(assetBundleDirectory))
{
Directory.CreateDirectory(assetBundleDirectory);
}
//在目标文件位置生成android平台文件 未压缩 推荐使用BuildAssetBundleOptions.ChunkBasedCompression LZ4压缩 加载速度比LZ4HC快
//BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.None, BuildTarget.Android);
string targetPath = Application.dataPath + "/AssetBundles";//android assets文件夹
//string targetPath = Application.persistentDataPath + "/AssetBundles";
BuildPipeline.BuildAssetBundles(targetPath,BuildAssetBundleOptions.ChunkBasedCompression,BuildTarget.Android);
}
读取:
//加载Android资源 Assets/StreamingAssets
LoadABPackage("/prefabs/add.androidload", "add");
void LoadABPackage(string path,string prefabs) {//
读取apk包文件时 需要 "!assets"+path 需要加 "!"
AssetBundle ab1 = AssetBundle.LoadFromFile(Application.dataPath + "!assets"+path);
//资源文件放在文件下 /data/data/包名/files
AssetBundle ab1 = AssetBundle.LoadFromFile(Application.dataPath + "/assets"+path);
GameObject goPrefab = ab1.LoadAsset<GameObject>(prefabs);
GameObject luzhang = GameObject.Instantiate<GameObject>(goPrefab);
Application.persistentDataPath : /data/data/xxx.xxx.xxx/files
Application.temporaryCachePath : /data/data/xxx.xxx.xxx/cache
//将文件下载到相关目录中 通过AssetBundle.LoadFromFile 加载指定目录进行资源读取
AssetBundle ab1 = AssetBundle.LoadFromFile(Application.persistentDataPath + "/assets"+path);
Log.e("External", "FilesDir===" + getExternalFilesDir("").getAbsolutePath());
Log.e("External", "StorageDirectory===" + Environment.getExternalStorageDirectory().getAbsolutePath());
Log.e("External", "getExternalStoragePublicDirectory===" + Environment.getExternalStoragePublicDirectory("").getAbsolutePath());
Log.e("External", "CacheDir===" + getExternalCacheDir().getAbsolutePath());
**Application.persistentDataPath : /data/data/xxx.xxx.xxx/files**
**Application.temporaryCachePath : /data/data/xxx.xxx.xxx/cache**
**getExternalFilesDir("").getAbsolutePath()) FilesDir===/storage/emulated/0/Android/data/com.skyworth.game.fruit/files**
**getExternalCacheDir().getAbsolutePath() CacheDir===/storage/emulated/0/Android/data/com.skyworth.game.fruit/cache**
StorageDirectory===/storage/emulated/0
getExternalStoragePublicDirectory===/storage/emulated/0