20.Resources资源加载:基本实现

Unity 资源加载的两种方式:Resources和AssetBundle最详细的解析 前言: 在游戏开发学习初期,游戏体量较小,如果游戏场景需要Asset中的资源,我们可能会通过拖动的方式,将其添加到游戏场景中。而到了实际工作中,会发现再这样做就会使得各种拖动的资源非常复杂,难以查找与维护 关于资源: 在Unity中,在Asset文件下的文件都可以称为游戏的资源,例如预制体、模型、材质、纹理、音频、视频、数据文档、场景等等 为了避免这样的情况,Unity游戏引擎为我们提供了很多种加载Asset中资源的方式,而我们最常用的主要是Resources和AssetBundle两种方式 资源加 阅读详情

一、实现目标

将 Resources 的加载和卸载方法统一封装到 ResMgr 中:

  • 同步加载资源。
  • 异步加载资源。
  • 卸载指定资源。
  • 异步卸载未使用资源。
    ResMgr 继承非 MonoBehaviour 单例基类:
public class ResMgr : BaseManager<ResMgr>

由于普通 C# 类不能直接开启协程,异步操作需要通过 MonoMgr 执行。

二、同步加载

public T Load<T>(string path) where T : UnityEngine.Object
{
    return Resources.Load<T>(path);
}
  • T:需要加载的资源类型。
  • path:资源相对于 Resources 文件夹的路径。
  • 返回值:加载到的资源对象。
    调用示例:
GameObject prefab = ResMgr.Instance.Load<GameObject>("Test");
GameObject obj = Object.Instantiate(prefab);

Load() 只负责加载资源,Instantiate() 才会在场景中创建实例。

三、泛型异步加载

外部调用方法:

public void LoadAsync<T>(string path,UnityAction<T> callBack)
    where T : UnityEngine.Object
{
    MonoMgr.Instance.StartCoroutine(ReallyLoadAsync(path, callBack));
}

真正执行异步加载的协程:

private IEnumerator ReallyLoadAsync<T>(string path,UnityAction<T> callBack)
    where T : UnityEngine.Object
{
    ResourceRequest request = Resources.LoadAsync<T>(path);
    yield return request;
    callBack?.Invoke(request.asset as T);
}

执行流程:

调用 LoadAsync<T>()
        ↓
MonoMgr 开启协程
        ↓
Resources.LoadAsync<T>()
        ↓
等待 ResourceRequest完成
        ↓
通过回调返回加载结果

调用示例:

ResMgr.Instance.LoadAsync<GameObject>("Test", prefab =>
{
    if (prefab != null)
    {
        Instantiate(prefab);
    }
});

四、Type 异步加载

不知道具体泛型类型,或者类型需要在运行时传入时,可以使用 Type:

public void LoadAsync(
    string path,
    System.Type type,
    UnityAction<UnityEngine.Object> callBack)
{
    MonoMgr.Instance.StartCoroutine(
        ReallyLoadAsync(path, type, callBack)
    );
}
private IEnumerator ReallyLoadAsync(
    string path,
    System.Type type,
    UnityAction<UnityEngine.Object> callBack)
{
    ResourceRequest request = Resources.LoadAsync(path, type);

    yield return request;

    callBack?.Invoke(request.asset);
}

调用后得到的是 UnityEngine.Object,使用前需要转换类型:

ResMgr.Instance.LoadAsync(
    "Test",
    typeof(GameObject),
    asset =>
    {
        GameObject prefab = asset as GameObject;

        if (prefab != null)
        {
            Instantiate(prefab);
        }
    }
);

五、两种异步加载的区别

方式回调结果特点
LoadAsync<T>()指定类型 T类型明确,使用方便
LoadAsync(path, type)UnityEngine.Object类型可在运行时决定,使用前需要转换

六、卸载指定资源

public void UnloadAsset(UnityEngine.Object assetToUnload)
{
    if (assetToUnload != null)
    {
        Resources.UnloadAsset(assetToUnload);
    }
}

Resources.UnloadAsset() 用于卸载单个资源,例如纹理、材质或音频资源;不能用它卸载场景实例、GameObject、Component 或 AssetBundle。场景中通过 Instantiate() 创建出的实例,应使用:

Destroy(gameObject);

不能使用 Resources.UnloadAsset() 代替实例销毁。

七、卸载未使用资源

public void UnloadUnusedAssets(UnityAction callBack = null)
{
    MonoMgr.Instance.StartCoroutine(
        ReallyUnloadUnusedAssets(callBack)
    );
}
private IEnumerator ReallyUnloadUnusedAssets(UnityAction callBack)
{
    AsyncOperation operation = Resources.UnloadUnusedAssets();

    yield return operation;

    callBack?.Invoke();
}

执行过程:

Resources.UnloadUnusedAssets()
        ↓
异步清理当前未使用的 Resources 资源
        ↓
清理完成后执行回调

该操作不应频繁调用,通常在切换场景或确定需要集中清理资源时使用。

八、使用注意事项

  1. 资源必须放在名为 Resources 的文件夹中。
  2. 路径相对于 Resources 文件夹,不写文件扩展名。
  3. 子文件夹路径使用 /,例如:
"Prefabs/Player"
  1. 异步加载结果可能为 null,使用前应判空。
  2. ResMgr 不是 MonoBehaviour,必须通过 MonoMgr 开启协程。

九、完整代码

  1. ResMgr.cs
using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;

/// <summary>
/// Resources 资源加载管理器。
/// </summary>
public class ResMgr : BaseManager<ResMgr>
{
    private ResMgr()
    {
    }

    /// <summary>
    /// 同步加载资源。
    /// </summary>
    /// <typeparam name="T">资源类型。</typeparam>
    /// <param name="path">Resources 文件夹下的相对路径。</param>
    public T Load<T>(string path)
        where T : UnityEngine.Object
    {
        return Resources.Load<T>(path);
    }

    /// <summary>
    /// 使用泛型异步加载资源。
    /// </summary>
    public void LoadAsync<T>(
        string path,
        UnityAction<T> callBack)
        where T : UnityEngine.Object
    {
        MonoMgr.Instance.StartCoroutine(
            ReallyLoadAsync(path, callBack)
        );
    }

    /// <summary>
    /// 真正执行泛型异步加载的协程。
    /// </summary>
    private IEnumerator ReallyLoadAsync<T>(
        string path,
        UnityAction<T> callBack)
        where T : UnityEngine.Object
    {
        ResourceRequest request =
            Resources.LoadAsync<T>(path);

        yield return request;

        callBack?.Invoke(request.asset as T);
    }

    /// <summary>
    /// 根据 Type 异步加载资源。
    /// </summary>
    public void LoadAsync(
        string path,
        Type type,
        UnityAction<UnityEngine.Object> callBack)
    {
        MonoMgr.Instance.StartCoroutine(
            ReallyLoadAsync(path, type, callBack)
        );
    }

    /// <summary>
    /// 真正执行 Type 异步加载的协程。
    /// </summary>
    private IEnumerator ReallyLoadAsync(
        string path,
        Type type,
        UnityAction<UnityEngine.Object> callBack)
    {
        ResourceRequest request =
            Resources.LoadAsync(path, type);

        yield return request;

        callBack?.Invoke(request.asset);
    }

    /// <summary>
    /// 卸载指定的单个资源。
    /// 不能用于销毁场景中的 GameObject 实例。
    /// </summary>
    public void UnloadAsset(
        UnityEngine.Object assetToUnload)
    {
        if (assetToUnload == null)
            return;

        Resources.UnloadAsset(assetToUnload);
    }

    /// <summary>
    /// 异步卸载当前没有使用的资源。
    /// </summary>
    ///`Resources.UnloadAsset()` 主要用于卸载资源本身,不是拿来直接销毁场景里的 GameObject
    public void UnloadUnusedAssets(
        UnityAction callBack = null)
    {
        MonoMgr.Instance.StartCoroutine(
            ReallyUnloadUnusedAssets(callBack)
        );
    }

    /// <summary>
    /// 真正执行资源清理的协程。
    /// </summary>
    ///> 开始异步卸载当前没有被任何地方引用的资源。`UnloadUnusedAssets()` 不需要你指定某个资源。Unity 会自己检查哪些资源已经没人用了,然后回收它们。
    private IEnumerator ReallyUnloadUnusedAssets(
        UnityAction callBack)
    {
        AsyncOperation operation =
            Resources.UnloadUnusedAssets();

        yield return operation;

        callBack?.Invoke();
    }
}
  1. Main.cs
using UnityEngine;

public class Main : MonoBehaviour
{
    private GameObject currentObj;

    private void Start()
    {
        // 泛型异步加载
        ResMgr.Instance.LoadAsync<GameObject>(
            "Test",
            prefab =>
            {
                if (prefab == null)
                {
                    Debug.LogError(
                        "Resources 中没有找到 Test"
                    );
                    return;
                }

                currentObj = Instantiate(prefab);
            }
        );

        // Type 异步加载
        ResMgr.Instance.LoadAsync(
            "Test",
            typeof(GameObject),
            asset =>
            {
                GameObject prefab = asset as GameObject;

                if (prefab == null)
                {
                    Debug.LogError(
                        "加载结果不是 GameObject"
                    );
                    return;
                }

                Instantiate(prefab);
            }
        );
    }

    private void Update()
    {
        // 按下空格测试同步加载
        if (Input.GetKeyDown(KeyCode.Space))
        {
            GameObject prefab =
                ResMgr.Instance.Load<GameObject>("Test");

            if (prefab != null)
            {
                Instantiate(prefab);
            }
        }

        // 按下 U 清理未使用资源
        if (Input.GetKeyDown(KeyCode.U))
        {
            ResMgr.Instance.UnloadUnusedAssets(() =>
            {
                Debug.Log("未使用资源清理完成");
            });
        }

        // 按下 D 销毁场景实例
        if (Input.GetKeyDown(KeyCode.D) &&
            currentObj != null)
        {
            Destroy(currentObj);
            currentObj = null;
        }
    }
}
Unity中Resources.Load加载资源及其封装 1.Resources介绍 Resources文件夹是Unity中标志性的目录(可以在1级目录,也可以在其他子目录),Resources目录下的文件不论使用与否,都会被强制打包到游戏包中,所以应尽可能去除不需要运行时加载的资源或者已经废弃掉的资源,否则会增大游戏包体积。且Resources下的文件不要直接当作预制体引用在场景中,否则会被Scene和Resources打包成两份,而应该在打开场景时加... 阅读详情

相关推荐

Unity3D Resources Load 资源加载测试

先摘一段Unity 文档上关于Resources.Load的相关说明: Resources.Load 加载: 加载储存在Resources文件夹中path处的资源 如果查找到资源,返回所在path处的资源,否则返回null。只有type类型的物体将被返回,path相对于Resources文件夹,扩展名必须被忽略。 Resources文件夹可以在Asserts文件夹中的任何位置。

mxlcl0557的专栏 2万+

Unity:资源加载 Resources.Load

为了降低耦合度,引入了资源加载, 就是将做好的游戏对象预制体,在脚本中通过加载资源路径的方式加载,有别于拖线形式. eg:拖线形式 public GameObject xxPrefab; GameObject.Instantiate(xxPrefab, _pos, Quaternion.identity); //创建行星​ 此外还需要将做好的游戏预制体拖到相应的检视...

u013509878的博客 4万+

Unity中的Resources加载

Unity的Resources加载是一种简单、直接的资源加载方式,适用于小型项目或特定场景。通过将资源放入Resources文件夹并使用Resources.Load或Resources.LoadAsync,开发者可以轻松实现运行时资源加载。然而,由于其在内存管理、性能和灵活性方面的局限性,开发者需要谨慎使用,并根据项目需求选择合适的资源管理方案。对于需要更高级功能的项目,Addressables是更好的选择。

ZeroBugX的博客 1162

Unity中Resources资源加载

/Resources动态加载资源的方法//让拓展性更强//相对拖曳来说 它更加一劳永逸 更加方便//重要知识点://记住API//记住一些特定的格式//预设体加载出来一定要实例化。

2301_79609157的博客 1076

unity资源加载

资源加载 AssetBundle Resources

qmladm的博客 2154

ArcGIS小白必看:如何用3D Analyst工具将二维点线秒变三维模型(附详细步骤)

本文为ArcGIS初学者提供了利用3D Analyst工具将二维点、线数据快速转换为三维模型的完整指南。详细讲解了基于属性字段和数字高程模型(DEM)两种核心方法,并附上从数据准备、工具操作到三维场景可视化与问题排查的详细步骤,帮助用户轻松实现从平面到立体的空间数据建模。

nft7creator的博客 140

Unity基础3——Resources资源动态加载

​ Resources 动态加载资源的方法,让拓展性更强。相对拖曳来说,它更加一劳永逸,更加方便。

weixin_53163894的博客 6056

IQA图像质量评价 数据集介绍(LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K)

LIVE、TID2013、CSIQ、LIVEC、KonIQ-10K 数据集介绍

qq_37925923的博客 1万+

Unity中Resources资源动态加载知识点详解

本文总结了Unity中的特殊文件夹路径获取及资源加载方法。主要包含:1)工程路径、Resources、StreamingAssets等特殊文件夹的作用和获取方式;2)Resources资源同步加载的通用方法,包括预设体、音效、文本等不同类型资源的加载;3)异步加载的实现方式及注意事项;4)资源卸载的两种方法。重点介绍了Resources文件夹的特点和使用规则,包括资源加载、内存管理及性能优化等内容,为Unity开发中的资源管理提供了实用指导。

徽程22级的在读学生 1600

彻底解决0x80070005错误代码:全面分析与实战指南

0x80070005错误代码虽然令人头疼,但通过上述方法,我们完全有能力将其攻克。从检查磁盘空间、设置账号权限,到运行疑难解答和系统文件检查器,再到调整相关服务状态,每一步都是解决这一问题的关键。希望本文能为你提供有力的帮助,让你在使用Windows系统的过程中更加顺畅无忧。

nntxthml的博客 6931

V-Mamba:2D 选择性扫描状态空间模型图像分类

V-Mamba CIFAR-10 分类链路:32² RGB → Stem Conv (3→64ch, stride2→16²) → VMambaBlock ×4 (SS2D 四方向 → Mamba S6 扫描 → MLP) → GAP → Linear → 10 类。核心贡献:SS2D 四方向扫描将 2D 空间建模转为 4 个 1D 序列, 计算复杂度从 O(N²) 降至 O(N)。建议先从 CIFAR-10 dim=64 depth=4 验证 SSM 收敛性;

FJN110的博客 70

Resources 资源加载及引入外部资源

Resources 资源加载 加载res中的资源,都是通过getResources()获取的,但是Resources是在什么时候被创建的呢,如何通过Resources获取到对应的资源的呢? XmlResourceParser layout = getResources().getLayout(R.layout.activity_change_skin); int color = getResour...

fengluoye2012的博客 9041

1000Base-T1协议解读(基于802.3bq-2016 和Test Suite)

1000Base-T1是由一对双绞线实现全双工传输的以太网标准,采用PAM3编码方式(-1,0,1),编码后的实际传输符号速率为750Mbps。该标准的车载最大传输距离可达15米,主要应用于汽车产品开发过程。测试过程示波器要求带宽≥2G,采样率≥7.5Gbps,网分带宽≥1G。

qflook的博客 5331

Unity学习笔记:Resources资源动态加载

关于Resources Resources资源加载 Resources资源卸载

游戏开发 4335

升级conda时出现Malformed version string invalid chars错误解决方案

但有时,当你使用“conda upgrade”的命令时,你可能会遇到一个错误,提示你的环境解析失败,出现“Malformed version string invalid chars”错误消息。如果以上两个步骤都没有解决你的问题,那么你可以考虑更新conda的依赖项。如果你的conda版本已经是最新的,那么你需要清理conda的缓存。最后,如果以上方法都无法解决问题,你可以尝试使用pip进行更新。如果你的conda版本过旧,你需要先更新conda。首先,你需要确认你当前使用的conda版本。

BUG?不存在的! 1409

构建基于知识图谱的金融风险关联网络

在金融领域,风险的识别和管理至关重要。传统的风险分析方法往往只能处理单一维度的数据,难以全面捕捉金融市场中复杂的风险关联关系。构建基于知识图谱的金融风险关联网络的目的在于整合多源异构的金融数据,通过知识图谱的方式清晰地展示金融实体之间的复杂关系,从而更准确地识别潜在的金融风险,为金融机构的风险管理决策提供有力支持。本项目的范围涵盖了从金融数据的收集、预处理,到知识图谱的构建,再到金融风险关联网络的搭建和分析。

SuperAGI2025 1418

Unity3D资源加载Resources

Unity3D资源加载Resources 目录 1、博客介绍 2、内容 3、推送 4、结语 1、博客介绍 本篇博客对资源加载类Resources做一个介绍 2、内容 FindObjectsOfTypeAll 返回一个该类型对象的列表 Load 从Resources文件夹内加载一个路径的资源 LoadAll...

孙君的空间站 4227

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

Resources加载慢?教你3步实现毫秒级资源加载响应

解决Unity资源加载卡顿问题,教你优化Unity C# Resources加载资源的3个关键步骤。适用于游戏启动、场景切换等高频场景,实现毫秒级响应速度,提升运行效率。方法简单易行,值得收藏。

IterStream的博客 931

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Resources资源同步加载与异步加载

资源同步加载、资源异步加载和资源卸载的方法

shadowsghost的博客 2664

Unity——Resources资源/场景动态加载

使用协程异步加载场景,会导致加载后脚本消失,不处理后续逻辑,所以要在开启协程的代码后加上“DontDestroyOnLoad(this.gameObject);本质就是将需要使用的资源直接放在Resources/子文件夹下,使用api获取,不拖拉获取。//卸载不使用资源,常用过场景时候。4,特点:项目导出,不会对该文件夹加密压缩,可读可写(移动端特别点,只读)。3,功能:将动态创建的文件资源,放入,比如json用的这个就是这个文件夹。2,获取:没必要,也没有api支持在导出项目后查找他的路径。

2401_83430690的博客 1104

加载资源:Assets,Resources,AssetsBundle(在线更新)

1、Assets(在编辑器环境加载) 2、Resources(游戏运行时加载) 3、AssetsBundle(在线更新) Resources Resources类只能读取名为“Resources”的文件夹里的资源,注意是复数形式。Resources文件夹需要用户自己新建,建议创建并放在Asset文件夹的根目录下。Unity打包发布时,Resources文件夹里的资源

星宇的专栏 3913

Resources加载资源

注意: 资源必须放在Resources目录下 资源路径相对于Resources目录,且不加后缀名 即使是后缀不同的资源,也不要重名,否则加载的时候要指定类型。 路径使用正斜杠”/” Resources中的所有资源,都会被打到客户端中 void Start() { GameObject go = GameObject.CreatePrimitive(PrimitiveType.

晓龙想飞 的专栏 1万+

Unity(二)——Resources资源动态加载

作用:需要通过Resources相关的API,该文件夹下的所有文件都会被打包出去,打包时Unity会对其压缩加密,该文件夹打包后只读,只能通过Resources相关API加载。作用:打包出去不会被压缩加密,移动平台只读,PC端可读可写,可以放入一些需要自定义动态加载的初始资源。通过代码动态加兹安Resources文件夹下指定路径资源,避免繁琐的拖曳动作。注意:预设体对象加载需要实例化,其他资源加一般直接用。1.通过异步加载中的完成事件监听,使用加载的资源。后面是在Resources文件下的文件路径。

2401_87775776的博客 1018

Unity3D:动态加载资源(Resources.Load与AssetBundle.LoadAsset)

Unity3D动态加载一(Resources) 在Unity3D中Project视窗中创建文件夹:Resources。 将需要动态加载的文件放入其中,例如Texture,Sprite,prefab等等。 在脚本中调用API接口Resources.Load()相关接口即可。 例如: using UnityEngine; using UnityEngine.UI; public class Lo...

Calmer的博客 7209

【Unity C#资源加载终极指南】:揭秘Resources加载性能瓶颈与优化策略

掌握Unity C# Resources加载资源的性能瓶颈与优化策略,提升项目运行效率。详解适用场景、异步加载与对象池等核心方法,减少内存开销,提高加载速度。适用于中小型项目资源管理,值得收藏。

PixelFlow的博客 1170
上一篇: 19.资源加载模块:主要作用和基本原理
下一篇: 21.Resources资源加载:异步加载优化
Unity黑马王子
博客等级 码龄4年 1846粉丝 181原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值