1.打包 (1)
在资源目录下创建一两个游戏物体 一个cube 一个红色材质球 将材质球拖给cube
cube命名为"cubeasset" 将cubeasset设为预制体
(2)
在prefab的属性查看器面板下面有一个名为AssetBundle的工具,接下来创建AssetBundleunity动态加载游戏对象,空的AssetBundle可以通过单击菜单选项”New...”来创建,将其命名为cubeasset。
这里特别需要注意,AssetBundle名字固定为小写,如果在名字中使用了大写字母橙光游戏,系统会自动转为小写格式
(3)创建脚本名为Exproter,同时创建一个文件夹,名字为"Editor",而且必须把这个脚本放在Editro文件夹下,原因见下文代码表述:
打开脚本,开始写代码:
!!!注意,我们这个脚本不需要任何脚本生命周期,因为我们执行打包不是在游戏进行时运行的,是在编辑状态下用的
using UnityEngine;
//引入Unity编辑器相关的命名空间 引入的这个命名空间 就需要创建同名Editor文件夹 然后将脚本放在Editor文件夹下
using UnityEditor;
引入UnityEditor这个命名空间是因为需要先写一个编辑器扩展,见代码:
//1.必须声明菜单函数的注解 参数里面是编辑器交互路径
//编辑器扩展脚本方法 这样就会在编辑器创建交互窗口
[MenuItem("ExportAsset/BuildAssetBundles")]
这一行代码写好后,刷新返回Unity,就会在Unity中看到多了一个选项,也就是我们写好的自定义扩展
再继续在脚本中写同名函数"BuildAssetBundles",当我们点击编辑器这个选项,就会执行脚本中的同名函数,代码以及解释:
//方法名和我们的编辑器选项名一致 当点击了这个编辑器选项就会执行脚本中的同名方法
//资源打包函数,用于将本工程内标注为AB的资源打成AB包
static void BuidAssetBundles()
{
//在编辑器中标识出AssetBundle资源标签,
//在下面代码基础上一键打包资源成为AB包到指定的资源文件目录
//传递三个参数(1.输出资源文件目录,2.打包选项,3.打包目标平台)
BuildPipeline.BuildAssetBundles("Assets/AssetBundles", BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
}
(4)返回Unity 点击编辑器扩展选项 执行脚本同名方法
就会在指定路径下生成打包好的资源包,忘记说了,在刚刚的代码中指定了路径AssetBundles,我们需要手动在编辑器创建好相对应的文件夹,不能无中生有哦,
这时打开文件夹,就会看到四个文件:
其中,有两种文件类型,一个是文本(Text Asset),另一个是(Default Asset),
默认的AssetBundles是对整个AB包资源的统计和描述文件 这个文件只会生成一个 其他的就是我们打包好的资源文件了 这个资源文件有两个类型,一个是文本类型的文件(Text Asset),这个存放的是对资源包的描述以及资源间依赖关系的文件,另一个(Default Asset)存放的就是资源内容本身了
2.AB包的加载和卸载
创建新的脚本,名为Inproter,用来对资源包加载和卸载,打开vs写代码:
!!!!注意,加载和卸载需要使用到脚本生命周期,这是在游戏运行时对资源进行动态的管理
using UnityEngine;
//AssetBundle资源包加载类,负责将此工程中的AB包资源加载到内存中使用
public class Inporter : MonoBehaviour
{
//声明资源包的引用 AssetBundde的类对象
AssetBundle ABRes;
void Start()
{
LoadContent();
}
//加载普通资源包中的内容到内存中并创建出其中的预制体游戏对象
public void LoadContent()
{
//在指定的路径中加载资源包到内存中 用ABRes来存放
ABRes = AssetBundle.LoadFromFile("Assets/AssetBundles/cubebundle");
//如果加载失败(可能出现内存不足等别的情况) 说明ABRes的内容为空
if (ABRes == null)
{
print("资源包加载失败");
return;
}
else
{
print("加载成功");
}
//从资源包中加载出单个预制体资源 使用LoadAsset方法加载指定的某一个资源
GameObject prefab = ABRes.LoadAsset("cubeasset");
//得到资源包中的预制体后,在场景中创建出预制体的游戏对象
Instantiate(prefab);
//遍历所有资源路径 这样会得到路径和文件名
//string[] AssetNames = ABRes.GetAllAssetNames();
//foreach (string name in AssetNames)
//{
// print("该资源包中的所有资源路径:"+name);
//}
//获取资源包中的所有资源,再取出每一个资源的名字
//该方法会得到资源包中的所有资源 返回的是Obj类型的数组
Object[] AssetObjs = ABRes.LoadAllAssets();
foreach (Object obj in AssetObjs)
{
print("资源包中的所有资源名:"+obj.name);
}
//加载完毕后 3S后卸载资源包
Invoke("UnLoadContents", 3.0f);
}
//加载完后卸载
//卸载资源包中所有已加载的内容
void UnLoadContents()
{
//1.只卸载还未加载的资源,不卸载已经加载的资源 场景中已经加载的资源不被受影响
//ABRes.Unload(false);
//2.无论是否加载,都卸载资源包中的所有资源
//执行true后 场景中的Cube的材质没了 但是Cube还在 因为卸载资源是卸载了游戏物体中指向的资源 但是这个游戏物体是在场景中被实例化了的
ABRes.Unload(true);
print("资源包已被卸载");
}
}
.AssetBundle.LoadAsset()
此方法通过使用资源名字标识作为参数,通过给定过的包的名称来加载资源。这个名字在项目视图中可见材质材料,并且开发者可以选择一个对象类型作为参数传递给加载方法以确保以一个特定类型的对象加载。
.AssetBundle.LoadAssetAsync()
此方法与上个方法相似,但是它并不会在加载资源的同时阻碍主线程,通过给定类型的包的名称异步加载资源。在加载大的资源或者短时间内加载很多资源的情况下能够很好的避免停止进程的发挥。
.AssetBundle.LoadAllAssets()
此方法将会加载AssetBundle中包含的所有资源对象,并且和AssetBundle.Load一样,你可以通过对象类型来过滤资源。
AssetBundle.Unload(false)->释放AssetBundle文件的内存镜像,不包含Load创建的Asset内存对象
AssetBundle.Unload(true)->释放AssetBundle文件的内存镜像unity动态加载游戏对象,并销毁所有Load创建的Asset内存对象
资源加载后我们就要及时卸载,避免占用内存,减少性能消耗
文章来源:https://blog.csdn.net/m0_69778537/article/details/130328960