Unity 之 Addressable可寻址系统 -- 资源加载和释放

news2024/11/13 8:57:44

可寻址系统资源 -- 加载和资源释放 -- 进阶(二)

  • 一,资源加载
    • 1.1 同步异步对比
    • 1.2 三种加载模式
  • 二,释放资源
    • 2.1 基础概念
    • 2.2 实例演示
      • 2.2.1 示例演示一
      • 2.2.2 示例演示二
    • 2.3 注意事项

概述:本篇文章从资源加载的方式和具体示例演示,为大家介绍可寻址资源系统的资源加载和资源释放。

一,资源加载

1.1 同步异步对比

同步异步相关概念:

同步:是指一个进程在执行某个请求的时候,如果该请求需要一段时间才能返回信息,那么这个进程会一直等待下去,直到收到返回信息才继续执行下去。

异步:是指进程不需要一直等待下去,而是继续执行下面的操作,不管其他进程的状态,当有信息返回的时候会通知进程进行处理。

举个简单的例子帮助理解:你打游戏口渴了想喝水

  • 同步实现:暂停游戏 下楼买 ——> 找附近超市 ——> 付款 喝水 ——> 回来继续游戏
  • 异步实现:游戏间隙 网上买 ——> 继续游戏 ——> 货到 喝水 ——> 继续游戏

实战中同步异步的对比

在一般加载中我们通常使用的:Instantiate 来实例化预制。

同步实例化问题:

  • 会等到实例化结束才继续运行
  • 大量加载容易造成卡顿。

使用AA系统时 使用InstantiateAsyns替换Instantiate :

异步实例化:

  • 系统不会等待
  • 调用完成时回来继续执行
  • 大量实例化不会卡住系统。

1.2 三种加载模式

Addressables资源加载模式有三个。

如下图,默认情况下是Use Asset Database (fastest):

  • Use Asset Database (fastest): 快速,直接加载文件而不打包。一般在开发时使用此模式。
  • Simulate Groups (advanced): 在不打包的情况下模拟AssetBundle的操作。
  • Use Exising Build: 实际上是从AssetBundle打包和加载。需要先通过Build打包,才能使用,也可以加载本地和远程Bundle。

三种模式使用时机:

  • Fast Mode --> 研发阶段
  • Virtual Mode --> 本地模拟
  • Packed Play Mode --> 正式打包

二,释放资源

2.1 基础概念

  1. 资源释放 不影响场景中实例化出的对象,但是会影响非实例化的资源(材质、音效等)。
  2. 释放后的资源,再次使用需要重新加载。
  3. 资源释放后AssetReference的资源引用(Asset)会清空 但AsyncOperationHandle类的资源引用(Result)不为空

2.2 实例演示

在:Windos -> Asset Management --> Addressables --> Event Viewer 打开工具面板:

找到Addressable 的设置面板,开启Send Profiler Events ,即可在Event Viewer面板上看到资源使用情况了:
在这里插入图片描述

此工具可以直观的看到,程序运行时的资源引用。

可寻址资源组还是用的前面文章中创建的:此处用到一个Cube,一个Logo,若你没看过之前的问题,新建一下这两个即可到默认分组即可:

2.2.1 示例演示一

使用InstantiateAsync实例化物体:

搭建测试场景,创建三个按钮分别为:实例化资源,删除实例化,释放资源:

测试代码如下:

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UI;

public class ReleaseManager : MonoBehaviour
{
    public Button Btn_Load;
    
    public Button Btn_Destory;
    
    public Button Btn_UnLoad;
    
    private GameObject Cube;
    
    void Start()
    {
        Addressables.InitializeAsync(); 
        
        Btn_Load.onClick.AddListener(LoadGameObject);
        Btn_Destory.onClick.AddListener(OnClickDestroyObj);
        Btn_UnLoad.onClick.AddListener(ReleaseGameObject);
        
    }

    /// <summary>
    /// 加载物体 
    /// </summary>
    void LoadGameObject()
    {
        Addressables.InstantiateAsync("Cube").Completed += (hal) =>
        {
            Cube = hal.Result;
        };
    }
    
    /// <summary>
    /// 释放
    /// </summary>
    void ReleaseGameObject()
    {
        Addressables.Release(Cube);
    }

    /// <summary>
    /// 销毁
    /// </summary>
    void OnClickDestroyObj()
    {
        Destroy(Cube);
        // 会自动调用Destroy,销毁物体
        //Addressables.ReleaseInstance(Cube);
    }
}

依次点击三个按钮资源引用情况如下:
请添加图片描述
为了做演示,我这里将资源释放和销毁分开写了,实战中若需要销毁实例化物体可以直接写:

// 释放资源,并销毁物体
Addressables.ReleaseInstance(Cube);

2.2.2 示例演示二

使用LoadAssetAsync加载图片资源:

创建一个Button用来触发加载,一个RawImage用来接收显示加载的图片,还有一个名Manager空物体用来挂载脚本:

测试示例代码如下:

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.UI;

public class ReleaseTextureManager : MonoBehaviour
{
    public RawImage RawImg_Context;
    
    public Button Btn_LoadTexture;
        
    void Start()
    {
        Addressables.InitializeAsync(); 
        
        Btn_LoadTexture.onClick.AddListener(LoadTexture);
    }

    void LoadTexture()
    {
        Addressables.LoadAssetAsync<Texture2D>("Logo").Completed += (hal) =>
        {
            // 赋值 还原大小
            RawImg_Context.texture = hal.Result;
            RawImg_Context.SetNativeSize();
            // 释放资源
            Addressables.Release(hal);
        };
    }
}

运行看下效果:


2.3 注意事项

AA系统中的资源释放有两个方法一个是Release,另外一个ReleaseInstance。两个方法分别用于不同的情况。大致可以记忆为:Release释放不需要实例化资源,ReleaseInstance释放实例化资源。

一个错误使用示范:

使用LoadAssetAsync加载然后Instantiate实例化的,是不能通过ReleaseInstance来进行释放资源的,而通过Release来释放也只能传递handle来释放不能传递Cube这个游戏对象。

Addressables.LoadAssetAsync<GameObject>("Cube").Completed += (hal) =>
{
    Cube = Instantiate(hal.Result);
    handle = hal;
};

// 这么写释放不掉
//Addressables.ReleaseInstance(Cube);
        
// 这么写会报错
Addressables.Release(Cube);

// 正确释放方式
Addressables.Release(handle);
Destroy(Cube);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/165771.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring官方提供【CSRF攻击】解决方案

步入正文 Cookie cookie是我们常见用来保存用户态信息&#xff0c;cookie跟随我们的请求自动携带。在同一域名下的请求&#xff0c;cookie总是自动携带。 用户态: 当前登入者的用户信息 以上的特性会导致一个潜在漏洞-CSRF CSRF CSRF一般指跨站请求伪造。 跨站请求伪造&…

长安链合约标准协议启动建设,邀请社区用户评审

智能合约是区块链摆脱第三方&#xff0c;实现验证、执行业务逻辑的“看不见的手”。随着联盟链产业落地进入快车道&#xff0c;需要面对的应用场景更加多样&#xff0c;智能合约标准协议作为推动联盟链应用生态繁荣的重要一环也需要加速推进发展。 区块链技术正在发展中规范。…

PHP 连接 MySQL

PHP 5 及以上版本建议使用以下方式连接 MySQL : MySQLi extension ("i" 意为 improved)PDO (PHP Data Objects) 在 PHP 早期版本中我们使用 MySQL 扩展。但该扩展在 2012 年开始不建议使用。 我是该用 MySQLi &#xff0c;还是 PDO? 如果你需要一个简短的回答&…

C语言 栈的应用 计算简单的中缀表达式

代码简介&#xff1a;下面的代码实现了计算简单的中缀表达式&#xff1a;只可以处理一位正整数的四则运算及括号。是栈的简单应用&#xff0c;要实现中缀表达式运算需要用两个栈&#xff0c;一个存储数字的栈和一个存储运算符的栈&#xff0c;因为懒得写两遍不同的栈上的操作&a…

增益自适应PI控制器+死区过滤器(Smart PLC向导PID编程应用)

增益自适应和死区过滤器如果不和S7-200 SMART PLC PID向导组合实现,大家可以自行编写优化的PID指令。算法起始非常简单,具体实现过程大家可以参看下面的文章链接, 三菱增量式PID+死区过滤器 三菱PLC增量式PID算法FB(带死区设置和外部复位控制)_RXXW_Dor的博客-CSDN博客关于…

【论文简述】High-Resolution Optical Flow from 1D Attention and Correlation(ICCV 2021)

一、论文简述 1. 第一作者&#xff1a;Haofei Xu 2. 发表年份&#xff1a;2021 3. 发表期刊&#xff1a;ICCV 4. 关键词&#xff1a;光流、代价体、自注意力、高分辨率、GRU 5. 探索动机&#xff1a;小分辨率对于网络性能有影响&#xff0c;并且现实场景中大多为高分辨率的…

Minecraft 1.19.2 Fabric模组开发 04.动画效果方块

我们本次尝试在1.19 Fabric中制作一个具有动画效果的方块 效果演示效果演示效果演示 首先&#xff0c;请确保你的开发包中引入了geckolib依赖&#xff0c;相关教程请参考:Minecraft 1.19.2 Fabric模组开发 03.动画生物实体 1.首先我们要使用geckolib制作一个物品和对应的动画…

eCharts工具类

ECharts是一款基于JavaScript的数据可视化图表库&#xff0c;提供直观&#xff0c;生动&#xff0c;可交互&#xff0c;可个性化定制的数据可视化图表。ECharts最初由百度团队开源&#xff0c;并于2018年初捐赠给Apache基金会&#xff0c;成为ASF孵化级项目。 ECharts官方地址…

【数据结构与算法】顺序表的原理及实现

1.什么是顺序表 顺序表是用一段物理地址连续的存储单元进行存储元素的线性结构&#xff0c;通常是以数组进行存储。通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系。 2.顺序表的实现 判断顺序表是否为空表public boolean isEmpty()判断顺序表是否满publi…

excel功能小技巧:自动求和的注意事项

在EXCEL里有个非常方便的按钮&#xff0c;叫做自动求和。不需要输入公式&#xff0c;直接一点&#xff0c;即可得出求和结果。由于它操作上的便利&#xff0c;所以深受小白喜爱。不过看着简单的自动求和按钮&#xff0c;实际上却藏着不少暗坑&#xff0c;稍不留神&#xff0c;可…

juc系列(2)--线程的使用及原理

目录线程创建线程ThreadRunnableCallable线程方法APIrun startsleep yieldjoininterrupt打断线程打断 park终止模式daemon不推荐线程原理运行机制线程调度未来优化线程状态查看线程线程 创建线程 Thread Thread 创建线程方式&#xff1a;创建线程类&#xff0c;匿名内部类方…

R-P-Faster R-CNN day65 读论文:高分辨率遥感影像综合地理空间目标检测框架

An Efficient and Robust Integrated Geospatial Object Detection Framework for High Spatial Resolution Remote Sensing Imagery 1. Introduction3. Overview of the Proposed R-P-Faster R-CNN Framework3.1. 有效集成区域建议网络与目标检测Faster R-CNN框架3.1.2. RPN与…

java反射在spring ioc和aop中的应用

java反射在spring ioc和aop中的应用 反射&#xff1a; 1.反射是什么&#xff1f; 程序运行时&#xff0c;通过类名能够获得类的属性和方法。使用方式如下 Class clazz Class.ForName(“Student”)Class clazz Student.class;Class clazz student.getClass(); 获取到claz…

java JUC 中 Object里wait()、notify() 实现原理及实战讲解

1.Object中的wait()实现原理 在进行wait()之前&#xff0c;就代表着需要争夺Synchorized&#xff0c;而Synchronized代码块通过javap生成的字节码中包含monitorenter和monitorexit两个指令。 当在进加锁的时候会执行monitorenter指令&#xff0c;执行该指令可以获取对象的mon…

前端与HTML

本节课程围绕“前端要解决的基本问题”及“什么是 HTML ”两个基本问题展开&#xff0c;了解 HTML 高效的编写原则。 什么是前端 使用web技术栈解决多端的人机交互问题 技术栈 html&#xff08;内容&#xff09; css &#xff08;样式&#xff09;javascript &#xff08;行…

linux部署KubeSphere和k8s集群

上一篇文章讲述了在单个节点上安装 KubeSphere和k8s&#xff0c;这节主要讲解k8s多节点集群部署 准备环境&#xff1a;Alibaba Cloud Linux系统3台机器第一步&#xff1a;设置主机名称hostname--(3台机器都设置) hostnamectl set-hostname master hostnamectl set-hostname nod…

智云通CRM:为什么你总是在请客,但业绩却上不来?

王总是一位企业老板&#xff0c;社会资源比较好&#xff0c;在过去的一年里&#xff0c;他新代理的一个保健品的项目&#xff0c;需要销售产品和招募合伙人。他想利用自己的人脉资源做销售&#xff0c;但他的销售过程并不顺利&#xff0c;在连续主动邀约之后效果不佳。 于是他…

2023/1/15 JS-变量提升与函数提升 执行上下文

1 变量提升与函数提升 变量声明提升 通过 var 声明的变量&#xff0c;在声明语句之前就可以访问到 - 值: undefined <script>console.log(a); // undefinedvar a 10 </script>函数声明提升 通过 function 声明的函数, 在声明语句之前就可以直接调用 - 值: 函数…

走近软件生态系统

生态系统&#xff08;Ecosystem&#xff09;原本是一个生物学术语&#xff0c;意思是由一些生命体相互依存、相互制约而形成的大系统&#xff0c;就像我们学生时代在生物学课堂上学到的那样。隐喻无处不在&#xff0c;人们把这个术语移植到了 IT 领域中来&#xff0c;比如我们常…

计算机基础(六):静态链接与动态链接

上一篇文章简单概括了 C语言程序经过编译&#xff0c;生成汇编语言、机器语言的基本过程。今天主要介绍其中链接阶段的实现思路。 静态链接 静态链接是将被依赖的代码片段复制到执行程序中&#xff0c;进行代码整合。因为我们在汇编代码中看到的是具体的符号&#xff0c;而且…