YooAssets初体验

版本号 创建/更新时间 操作
V1.0 2023-07-13 09:10:43 创建
V1.1 2023-07-19 09:33:17 添加着色器变体说明

YooAssets 是一个资源管理工具,基于ab包实现。

通过YooAssets 可以方便的对资源进行管理、分析、更新。

快速食用

打开管理界面 Edit/Project Settings/Package Manager

1
2
3
4
// 输入以下内容(中国版)
Name: package.openupm.cn
URL: https://package.openupm.cn
Scope(s): com.tuyoogame.yooasset

在包管理器中安装YooAssets

划分组别

image-20230714093639774

构建工具

image-20230714093947222

报告工具

在打包后可以使用报告工具查看相关数据:

image-20230714094110038

调试工具

image-20230714094332240

模式

模式 说明
编辑器模式EditorSimulateMode 无需构建,直接使用
离线模式OfflinePlayMode 单机游戏使用
在线模式HostPlayMode 在线游戏热更新

代码范例

封装资源加载

我们可以对通用资源加载进行封装,使用1行代码实现资源加载。

封装资源加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
private async Task<T> LoadAsync<T>(string key) where T : class
{
key = key.Replace("/", "_");
if (_package.CheckLocationValid(key))
{
var handle = _package.LoadAssetAsync(key, typeof(T));
await handle.Task;

return handle.AssetObject as T;
}
else
{
Debug.LogError($"{key} 資源尋址地址錯誤!");
return null;
}
}

通用示例

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Scenes.YooTest;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.SceneManagement;
using YooAsset;

public class YooAssetTest : MonoBehaviour
{
private ResourcePackage _package;

private const string PackName = "DefaultPackage";

[SerializeField] private EPlayMode playMode;

private async void Start()
{
YooAssets.Initialize();
_package = YooAssets.CreatePackage(PackName);
YooAssets.SetDefaultPackage(_package);
InitializationOperation hand;
switch (playMode)
{
case EPlayMode.EditorSimulateMode:
//編輯器模式
var sm = new EditorSimulateModeParameters
{
SimulateManifestFilePath = EditorSimulateModeHelper.SimulateBuild(PackName)
};
hand = _package.InitializeAsync(sm);
await hand.Task;
break;
case EPlayMode.OfflinePlayMode:
//離線模式
hand = _package.InitializeAsync(new OfflinePlayModeParameters());
await hand.Task;
break;
case EPlayMode.HostPlayMode:
//在線模式
var hs = new HostPlayModeParameters()
{ QueryServices = new YooHostQuery(), RemoteServices = new YooRemote() };
hand = _package.InitializeAsync(hs);
await hand.Task;
if (hand.Status == EOperationStatus.Succeed)
{
Debug.Log("资源包初始化成功!当前资源版本:"+ _package.GetPackageVersion());
}
else
{
Debug.LogError($"资源包初始化失败:{hand.Error}");
}

StartCoroutine(HostLink());

break;
}
}

private IEnumerator HostLink()
{
//檢查版本
var upHandle = _package.UpdatePackageVersionAsync(false); //關閉時間戳
yield return upHandle;
if (upHandle.Status == EOperationStatus.Succeed)
{
//更新成功
string packageVersion = upHandle.PackageVersion;
Debug.Log($"已获取到最新版本号 : {packageVersion}");
HotConfig.NewVision = packageVersion;
}
else
{
//更新失败
Debug.LogError(upHandle.Error);
}

//更新資源
var upAssetHandle = _package.UpdatePackageManifestAsync(upHandle.PackageVersion, true);
yield return upAssetHandle;

if (upAssetHandle.Status == EOperationStatus.Succeed)
{
Debug.Log("更新完成!");
StartCoroutine(Download());
}
else
{
Debug.Log("更新失敗:" + upAssetHandle.Error);
}
}


private IEnumerator Download()
{
int downloadingMaxNum = 10;
int failedTryAgain = 3;
var package = _package;
var downloader = package.CreateResourceDownloader(downloadingMaxNum, failedTryAgain);

print("需要下载的资源数量:"+downloader.TotalDownloadCount);
//没有需要下载的资源
if (downloader.TotalDownloadCount == 0)
{
yield break;
}

//需要下载的文件总数和总大小
int totalDownloadCount = downloader.TotalDownloadCount;
long totalDownloadBytes = downloader.TotalDownloadBytes;

//注册回调方法
downloader.OnDownloadErrorCallback = (x,a)=>{print("下载资源出错!");};
downloader.OnDownloadProgressCallback =(x,a,c,b)=>{print($"当前下载进度:{a}/{x}");};
downloader.OnDownloadOverCallback = (x)=>{print("下载完成");};
downloader.OnStartDownloadFileCallback = (x,a)=>{print("开始下载");};

//开启下载
downloader.BeginDownload();
yield return downloader;

//检测下载结果
if (downloader.Status == EOperationStatus.Succeed)
{
//下载成功
print("下载成功!");
}
else
{
//下载失败
print("下载失败:"+downloader.Error);
}
}

[Button]
private async void CreateUI()
{
var root = GameObject.Find("Canvas");
var go = await LoadAsync<GameObject>("UI/Image");
if (go)
{
Instantiate(go, root.transform, false);
}
}

[Button]
private async void CreateCube()
{
var g= await LoadAsync<GameObject>("UI/Cube");
Instantiate(g);
}

[Button]
private async void LoadScene()
{
var sc = _package.LoadSceneAsync("Scene_1", LoadSceneMode.Additive);
await sc.Task;
}
}

着色器变体收集

什么是着色器变体

当我们写完一个shader以后,unity需要加载和编译,这个过程由着色器的构建管线来完成,它的输入是着色器,而它的输出就是今天的主角—着色器变体;每一个着色器进入构建管线后会被解析,然后提取着色器片段(顶点着色器和片元着色器等),收集预处理指令,然后每一个着色器变体会有一个参数表;
————————————————
版权声明:本文为CSDN博主「莫之」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36383623/article/details/103327389

YooAsset 收集着色器变体

image-20230719095020282

收集的着色器变体文件需要打包进AB中,在AB中加载。

配合UnityCDN使用

PS:YooAsset通过获取版本号,再更新对应版本资源。

故可以将获取补丁文件的路径设置为动态的,通过获取到的版本号来获取对应资源,有利于资源在CDN的存储结构。

  1. 创建一个Bucket存储池:

image-20230714095638150

  1. 下载相关Unity 插件

image-20230714095811900

  1. 填写好相关key

  1. 上传相关文件

image-20230714100120217

相关链接