Unity Assetbundle

Unity Assetbundle

🎮

Assetbundle资源打包、加载、卸载

资源打包

打包素材标签名字格式 小写

“文件名+unity3d”


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using UnityEditor;

public class ABTools
{
//打包的核心方法
private static void BuildAssetBundle(BuildTarget buildTarget)
{
// 1. 确定资源打包的文件夹里面

string backOrignFold = Application.dataPath + "/../../Release/";
string assetFold = backOrignFold + buildTarget + "/StreamingAssets/";
// 2. 对文件的逻辑 如果文件夹存在则会删除,并重新创建
if (Directory.Exists(assetFold))
{
Directory.Delete(assetFold, true);
// 第一个参数是检测的目录,第二个参数是要不是删除掉
}

Directory.CreateDirectory(assetFold);
// 3. 往这个目录里打包文件
BuildPipeline.BuildAssetBundles(assetFold, BuildAssetBundleOptions.None, buildTarget);
//BuildPipeline.BuildAssetBundle已经被弃用
}

#region Platform 执行打包

[MenuItem("打包工具/PC")]
public static void buildAB_PC()
{
BuildAssetBundle(BuildTarget.StandaloneWindows);
}

[MenuItem("打包工具/Android")]
public static void buildAB_Android()
{
BuildAssetBundle(BuildTarget.Android);
}

[MenuItem("打包工具/iOS")]
public static void buildAB_iOS()
{
BuildAssetBundle(BuildTarget.iOS);
}

#endregion
}

explorer_QOriXYo6sx.png

manifest日志文件 包含了素材的一些基本信息

加载视频 或者是任何的资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Video;

public class ABManager : MonoBehaviour
{
// 1 确定资源被打包的路径
private string asset;

void Start()
{
asset = Application.dataPath + "/../../Release/StandaloneWindows/StreamingAssets/";
//播放视频 从AB中加载视频源

#region 加载资源 ⭐

LoadVideoFromAB();
LoadUIFromAB();
LoadAudioFromAB();

#endregion
}

void LoadVideoFromAB()
{
// 2 加载AssetBundle
AssetBundle ab = AssetBundle.LoadFromFile(asset + "cg.unity3d");
// 3 从AB中在加载资源
VideoClip clip = ab.LoadAsset<VideoClip>("cg.mp4");
VideoPlayer video = GameObject.Find("Canvas/RawImage").GetComponent<VideoPlayer>();
video.clip = clip;
video.Play();
}

void LoadUIFromAB()
{
// 2 加载AssetBundle
AssetBundle ab = AssetBundle.LoadFromFile(asset + "bg1.unity3d");
// 3 从AB中在加载资源
Sprite sprite = ab.LoadAsset<Sprite>("bg1.jpg");
Image image = GameObject.Find("Canvas/Image").GetComponent<Image>();
image.sprite = sprite;
}

void LoadAudioFromAB()
{
// 2 加载AssetBundle
AssetBundle ab = AssetBundle.LoadFromFile(asset + "bgaudio.unity3d");
// 3 从AB中在加载资源
AudioClip clip = ab.LoadAsset<AudioClip>("bgaudio.wav");
AudioSource audio = transform.GetComponent<AudioSource>();
audio.clip = clip;
audio.Play();
}
}

加载 prefab & scene

打包好的𝙥𝙧𝙚𝙛𝙖𝙗预制体依赖许多文件 包括网格、贴图、材质球等,如果直接加载是会丢失的,因此需要先把模型的依赖文件先加载出来,再产卵

代码如下👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
using UnityEngine.Video;

public class ABManager : MonoBehaviour
{
// 1 确定资源被打包的路径
private string asset;

void Start()
{
asset = Application.dataPath + "/../../Release/StandaloneWindows/StreamingAssets/";
//播放视频 从AB中加载视频源

#region 加载资源

// LoadVideoFromAB();
// LoadUIFromAB();
// LoadAudioFromAB();

//加载依赖项
GetAllDependencies("monster.unity3d");
//加载预制体
// LoadPrefabsFromAB();

#endregion
}

void LoadVideoFromAB()
{
// 2 加载AssetBundle
AssetBundle ab = AssetBundle.LoadFromFile(asset + "cg.unity3d");
// 3 从AB中在加载资源
VideoClip clip = ab.LoadAsset<VideoClip>("cg.mp4");
VideoPlayer video = GameObject.Find("Canvas/RawImage").GetComponent<VideoPlayer>();
video.clip = clip;
video.Play();
}

void LoadUIFromAB()
{
// 2 加载AssetBundle
AssetBundle ab = AssetBundle.LoadFromFile(asset + "bg1.unity3d");
// 3 从AB中在加载资源
Sprite sprite = ab.LoadAsset<Sprite>("bg1.jpg");
Image image = GameObject.Find("Canvas/Image").GetComponent<Image>();
image.sprite = sprite;
}

void LoadAudioFromAB()
{
// 2 加载AssetBundle
AssetBundle ab = AssetBundle.LoadFromFile(asset + "bgaudio.unity3d");
// 3 从AB中在加载资源
AudioClip clip = ab.LoadAsset<AudioClip>("bgaudio.wav");
AudioSource audio = transform.GetComponent<AudioSource>();
audio.clip = clip;
audio.Play();
}

public void LoadPrefabsFromAB()
{
// 2 加载AssetBundle
AssetBundle ab = AssetBundle.LoadFromFile(asset + "monster.unity3d");
// 3 从AB中在加载资源
GameObject go = ab.LoadAsset<GameObject>("monster.prefab");
GameObject go1 = GameObject.Instantiate(go);
go1.transform.position = Vector3.zero;
}

public void LoadSceneFromAB()
{
AssetBundle ab = AssetBundle.LoadFromFile(asset + "mobascene.unity3d");
SceneManager.LoadScene("mobascene");
}

private AssetBundle mainAB;
private AssetBundleManifest mainfest;
//🥝🥝🥝🥝🥝🥝🥝🥝🥝🥝🥝🥝🥝🥝👇核心部分
void GetAllDependencies(string ABName)
{
if (mainAB == null)
{
mainAB = AssetBundle.LoadFromFile(asset + "StreamingAssets");
}

if (mainfest == null)
{
mainfest = mainAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
}

//通过这个方法可以获取到它所依赖的资源 是一个数组
string[] dependencies = mainfest.GetAllDependencies(ABName);
if (dependencies.Length > 0)
{
foreach (var item in dependencies)
{
AssetBundle ab = AssetBundle.LoadFromFile(asset + item);
ab.LoadAllAssets();
//这就把每个资源都加载出来了
}
}
}
}

GbpNjXPqBv.png

资源的卸载

AssetBundle加载的文件都会被清理掉
为了释放内存,一般用在场景切换

1
2
3
4
5
6
7
8
9
10
11
12
13
private void Update()
{
if (Input.GetKeyDown(KeyCode.A))
{
//卸载所有的AB 以及通过AB加载出来的资源
AssetBundle.UnloadAllAssetBundles(true);
}
else if (Input.GetKeyDown(KeyCode.S))
{
//卸载掉未引用的包 比较安全
AssetBundle.UnloadAllAssetBundles(false);
}
}

测试只能使用一次,也就是说内存中将不存在

作者

发布于

2022-12-28

更新于

2023-01-10

许可协议