存储在Resources下的资源,最終会存储在游戏的主体包中,发送给用
户,手机系统上,如果需要做资源的更新,是无法使用Resources即时更新(不
需要关闭手机游戏,即可实现游戏更新)
AB包和Resources的区别
存储:
Resources内部资源存储在游戏的发布包中。
AB包存储在独立的文件中(AB包存储在非特殊目录下时,不在游戏的发布包中)。
加载:
Resources内部资源使用Resources.Load()。
AB包(可以理解为可下载的Resources))。
获得AB包文件(下载,解压streaming拷贝到可写目录)。
加载步骤1:通过AB包文件路径,加载AB包文件。
加载步骤2:通过名称(资源起名),加载内部资源。
AssetBundle的定义
AssetBundle是把一些资源文件, 场景文件或二进制文件以某种紧密的方式保存在
一起的一些文件。
AssetBundle.内部不能包含C#脚本文件,AssetBundle可以配合Lua实现资源和游戏。
逻辑代码的更新。
热更新。
不关闭Unity应用的前提,实现游戏资源和代码逻辑的更新
AB包的创建。
资源导入项目。
如果资源未来做更新(资源存储在AB包中),就不要将资源放置在Resources目录下。
选中需要添加AB包的资源,填写或选择已存在的AB包名称,
AB包配置修改后或AB内部的资源修改后,都需要重新生成AB包
AB包名称如果配置为这样的结构"ui/package" , ui会作为AB包存储的父目录,
package是AB包的名称.
生成AB包脚本编写(编辑器脚本)。
AB包压缩方式(根据实际情况分析)
不压缩: AB 包比较大,加载速度快(CPU 不用运算解压缩)。
LZMA算法压缩:默认压缩模式,文件尺寸居中,加载速度居中。.
LZ4算法压缩: 5.3 以后可用,压缩比例高,文件小,加载速度偏慢.
依赖关系。
如果一个AB (名称A)包,使用到了另一个AB (名称B)包的资源,那么两
个AB包就产生了依赖关系。也就是A依赖于B。。.
Package预制体,依赖于背包素材所在的AB包
编写项部菜单栏按钮。
AB包分平台,所以导出的API不同.
Androide
iOS.
Windowsv
Mac.
BuildPipeline.BuildAssetBundlesy
AB存储路径。
导出选项。
None: 无任何选项。
UncompressedAssetBundle: 默认LZMA,开启这个选项就不会压缩AB包
CollectDependencies: 默认开启,开启依赖记录机制。
DeterministicAssetBundle:将AssetBundle的哈希校验值,存储在ID中(默认开启)。
ForceRebuildAssetBundle:强制重新导出所有的AB包
ChunkBasedCompression:使用LZ4算法压缩AB包。
和存储目录同名的文件和文件.manifest,是主AB包及主AB包配置文件。
无扩展名文件: AB包
文件名.manifest文件: AB包对应的配置文件。
加载AB包内部数据。
如果想处理依赖关系的加载,则必须加载主AB包,因为依赖关系的存储,都存储在主AB包的配置文件中
第一步(加载依赖的AB包文件)。
1.加載主AB包,
2.根据主AB包的配置文件,获得我当前需要加载的AB所依赖的AB们。
3.将所有的依赖AB们,加载进来,
第二步(加载AB包文件)。
AB包= AssetBundle,LoadFromFile(AB包文件路径).
AssetBundle.LoadFromFileSync(AB包文件路径)
第三步(加载AB包内部资源)。
资源对象= AB包对象,LoadAsset<资源类型>(“资源名称”》。
AB包对象.LoadAssetSync<资源类型>(“资源名称")。
注意!!: AB包不能重复加载,
Resources.Load()加载后的资源,Unity 会存储在内存中,所以即使场景中的对象被.
删除,资源的内存占用依然存在,只用使用Resources.UnloadUnusedAssets()释放后,
没有被场景引用的资源内存才会被释放。
//简单的加载AB包
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class SimpleLoad : MonoBehaviour
{
private void Start()
{
//第一步 加载ab文件
AssetBundle ab= AssetBundle.LoadFromFile(Config.ABPath + "/ui");
//第二步 加载资源
Sprite sp= ab.LoadAsset<Sprite>("picture12");
GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite = sp;
}
}
//静态路径
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Config : MonoBehaviour
{
//配置ab包存储的路径
public static string ABPath = Application.dataPath.
Substring(0, Application.dataPath.Length - 6) + "ab";
}
//顶部菜单按钮导出AB包的编写
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEditor;
public class ExportAB
{
[MenuItem("AB包导出/导出Window平台")]
public static void ForWindow()
{
Export(BuildTarget.StandaloneWindows);
}
[MenuItem("AB包导出/导出Ios平台")]
public static void ForIos()
{
Export(BuildTarget.iOS);
}
[MenuItem("AB包导出/导出Android平台")]
public static void ForAndroid()
{
Export(BuildTarget.Android);
}
[MenuItem("AB包导出/导出Mac平台")]
public static void ForMac()
{
Export(BuildTarget.StandaloneOSX);
}
//导出方法
public static void Export(BuildTarget plantform)
{
//项目的Assets目录路径
string path = Application.dataPath;
//想要的路径(字符串截取)
path = path.Substring(0, path.Length - 6) + "ab";
//防止路径不存在
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
//导出ab包代码,生成ab包核心文件
//参数1.ab包文件存储路径,
//参数2.导出选项,
//参数3.平台(不同平台不一样)
BuildPipeline.BuildAssetBundles(path,
BuildAssetBundleOptions.ChunkBasedCompression|
BuildAssetBundleOptions.ForceRebuildAssetBundle,
plantform);
Debug.Log("导出ab包成功");
}
}
//热跟新的实现
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class HotUpdate : MonoBehaviour
{
public Image icon;
private void Start()
{
//第一步 加载ab文件
AssetBundle ab= AssetBundle.LoadFromFile(Config.ABPath + "/one/ui");
//第二步 加载资源
Sprite sp= ab.LoadAsset<Sprite>("picture13");
icon.sprite = sp;
ab.Unload(false);//释放ab包
}
//点击按钮后,加载新ab包里的资源
public void ChangeAB()
{
//第一步 加载ab文件
AssetBundle ab= AssetBundle.LoadFromFile(Config.ABPath + "/two/ui");
//第二步 加载资源
Sprite sp= ab.LoadAsset<Sprite>("picture111");
icon.sprite = sp;
ab.Unload(false);//释放ab包
}
}
//如果有依赖文件的化,得先加载主AB包,根据主AB包的配置文件,获取我们当前需要加载AB包所依赖的AB包们,把他们加载进来,再加载需要加载的AB包路径,再加载资源
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;
public class Load : MonoBehaviour
{
private void Start()
{
//加载主AB包
AssetBundle main=AssetBundle.LoadFromFile(Config.ABPath+"/ab");
//获取主AB包的配置文件
AssetBundleManifest mainfest = main.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//分析预制体所在AB包依赖哪些AB包 //deps存储了所有依赖ab包的名字
string[] deps= mainfest.GetAllDependencies("ui2");
//加载依赖的AB包
for (int i = 0; i < deps.Length; i++)
{
AssetBundle.LoadFromFile(Config.ABPath + "/" + deps[i]);
}
//加载预制体所在的AB包
AssetBundle ui2 = AssetBundle.LoadFromFile(Config.ABPath + "/ui2");
//加载预制体
Object prefab = ui2.LoadAsset("hahah");
GameObject hah=Instantiate(prefab) as GameObject;
hah.transform.SetParent(GameObject.Find("Canvas").transform);
hah.transform.localPosition=Vector3.zero;
hah.transform.localScale=Vector3.one;
//卸载依赖
ui2.Unload(false);
}
}
//异步加载AB包
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class AsyncLoad : MonoBehaviour
{
private void Start()
{
//同步加载Resources代码
// GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite=
// Resources.Load<Sprite>("tmp1/picture1") ;
//同步加载代码AB包代码
// AssetBundle ab= AssetBundle.LoadFromFile(Config.ABPath + "/big");
// GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite =
// ab.LoadAsset<Sprite>("picture1");
//开启协程,开启另一个代码加载Resources
//StartCoroutine(LoadImage());
//开启协程,开启另一个代码加载AB包
StartCoroutine(LoadAB());
}
//开启协程加载Resources
IEnumerator LoadImage()
{
ResourceRequest rr= Resources.LoadAsync<Sprite>("tmp1/picture1");
yield return rr;
GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite=
rr.asset as Sprite;
}
//开启协程加载AB包
IEnumerator LoadAB()
{
AssetBundleCreateRequest abcr = AssetBundle.LoadFromFileAsync(Config.ABPath + "/big");
yield return abcr;
GameObject.Find("/Canvas/Image").GetComponent<Image>().sprite =
abcr.assetBundle.LoadAsset<Sprite>("picture1");
}
}
//加载AB包时内存的使用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class Memory : MonoBehaviour
{
private AssetBundle ab;
public Image img;
public void LoadFile()
{
ab = AssetBundle.LoadFromFile(Config.ABPath + "/big");
}
public void LoadImage()
{
img.sprite = ab.LoadAsset<Sprite>("picture1");
}
public void UnLoadFile()
{
//true为卸载资源和依赖 false只卸载依赖
ab.Unload(false);
}
//内存回收,手动调用gc
public void Recycle()
{
//将所有没有再使用的资源进行回收
Resources.UnloadUnusedAssets();
}
//destory不会主动回收内存
public void Destory()
{
Destroy(img.gameObject);
}
}
//自己写的小工具
//加载有依赖的物体
public Object LoadABMainFest(string mainPath, string mainLoad,string needLoadName,string needName)
{
string ABPath = Application.dataPath.
Substring(0, Application.dataPath.Length - 6) + mainPath;
//加载主AB包
AssetBundle main=AssetBundle.LoadFromFile(ABPath+mainLoad);
//获取主AB包的配置文件
AssetBundleManifest mainfest = main.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
//分析预制体所在AB包依赖哪些AB包 //deps存储了所有依赖ab包的名字
string[] deps= mainfest.GetAllDependencies(needLoadName);
//加载依赖的AB包
for (int i = 0; i < deps.Length; i++)
{
AssetBundle.LoadFromFile(ABPath + "/" + deps[i]);
}
//加载预制体所在的AB包
AssetBundle assetBundle = AssetBundle.LoadFromFile(ABPath + "/"+needLoadName);
//加载预制体
Object prefab = assetBundle.LoadAsset(needName);
Object gameObject=Instantiate(prefab);
assetBundle.Unload(false);
return gameObject;
}
//加载没依赖的物体
public Sprite LoadAB(string mainPath,string needLoad,string loadName)
{
string ABPath = Application.dataPath.
Substring(0, Application.dataPath.Length - 6) + mainPath;
//第一步 加载ab文件
AssetBundle ab= AssetBundle.LoadFromFile(ABPath + needLoad);
//第二步 加载资源
Sprite sp= ab.LoadAsset<Sprite>(loadName);
ab.Unload(false);//释放ab包
return sp;
}
|