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

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

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

# 快速食用

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

// 输入以下内容(中国版)
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 行代码实现资源加载。

封装资源加载
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;
        }
    }

# 通用示例

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

# 相关链接

  • Hello from YooAsset | YooAsset
  • +UOS Developer Portal (unity.cn)
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

Fasty 微信支付

微信支付

Fasty 支付宝

支付宝

Fasty 贝宝

贝宝