Resources的资源加载管理器

代码分析

  1. ResInfoBaseResInfo<T>

    • ResInfoBase 是资源信息的基类,定义了一个 refCount 属性,用于记录资源的引用计数。
    • ResInfo<T> 是泛型类,用于保存具体类型 T 的资源信息。它包含了资源对象 asset、异步加载结束后的回调 callBack、协程对象 coroutine,以及 isDel 标志,决定是否在引用计数为0时真正移除资源。
  2. ResMgr 类:

    • 继承自 BaseManager<ResMgr>,实现了单例模式,保证资源管理器在整个项目中只有一个实例。
    • resDic 是一个字典,用于存储已经加载的资源以及其对应的资源信息(ResInfoBase)。
    • Load<T>:同步加载 Resources 下的资源,并根据路径和类型将资源存储在字典中。
    • LoadAsync<T>:异步加载资源,使用协程进行异步操作,并在加载完成后调用回调函数 callBack
    • UnloadAsset<T>:根据资源路径卸载不再使用的资源,通过引用计数系统确保资源安全地被卸载。
    • UnloadUnusedAssetsClearDic:分别提供了卸载未使用资源和清空字典的功能,优化内存。

案例:实现一个子弹对象的加载与复用

在一个射击类游戏中,子弹是频繁生成和销毁的对象。我们可以使用 ResMgr 实现一个子弹的加载和对象池复用,从而避免频繁的 InstantiateDestroy 操作,提升性能。

1. 准备工作:

  • 创建一个名为 Bullet 的子弹预制体,并将其保存在 Resources 目录下。
  • 编写 Bullet 类来处理子弹的逻辑,比如移动和销毁。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResBullet : MonoBehaviour
{
    public float speed = 10f;
    public float lifeTime = 2f;

    private void OnEnable()
    {
        Invoke(nameof(Recycle), lifeTime);
    }
    private void Update()
    {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
    }
    void Recycle()
    {
        ResMgr.Instance.UnloadAsset<GameObject>("ResBullet", true);
        gameObject.SetActive(false);
    }
}

2. 子弹生成管理器:

编写一个 BulletManager 类,负责生成子弹,并通过 ResMgr 管理子弹的加载和回收。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResBulletManager : BaseManager<ResBulletManager>
{
    public string bulletPrefabPath = "ResBullet";

    ResBulletManager() { }
    public void ShootBullet(Vector3 position, Quaternion rotation)
    {
        GameObject bullet = ResMgr.Instance.Load<GameObject>(bulletPrefabPath);

        if (bullet != null)
        {
            GameObject.Instantiate(bullet);
            bullet.SetActive(true);
            bullet.transform.position = position;
            bullet.transform.rotation = rotation;
        }
    }

    public void ShootBulletAsync(Vector3 position, Quaternion rotation)
    {
        Debug.Log("ShootBulletAsync");
        ResMgr.Instance.LoadAsync<GameObject>(bulletPrefabPath, (bullet) =>
        {
            Debug.Log("ShootBulletAsync1");
            if (bullet != null)
            {
                Debug.Log("ShootBulletAsync2");
                GameObject.Instantiate(bullet);
                bullet.SetActive(true);
                bullet.transform.position = position;
                bullet.transform.rotation = rotation;
            }
        });
    }

    public void RecycleBullet(GameObject bullet)
    {
        ResMgr.Instance.UnloadAsset<GameObject>("Bullet", true);
        bullet.SetActive(false);
    }
}

3. 测试步骤:

  • BulletManager 脚本挂载到主角或场景中的某个物体上。
  • 在游戏中按下某个按键时调用 ShootBulletShootBulletAsync 来发射子弹:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ResPlayerController : MonoBehaviour
{
    public Transform firePoint;
    private void Start()
    {
        
    }
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Debug.Log("Space");
            ResBulletManager.Instance.ShootBullet(firePoint.position, firePoint.rotation);
        }
        if (Input.GetKeyDown(KeyCode.A))
        {
            Debug.Log("A");
            ResBulletManager.Instance.ShootBulletAsync(firePoint.position, firePoint.rotation);
        }
    }
}

案例总结:

通过这个案例,你展示了如何使用 ResMgr 来管理子弹对象的加载与回收,从而避免频繁的实例化和销毁操作。ResMgr 提供了同步和异步加载两种方式,结合引用计数系统和资源池,能够有效优化资源管理,提高游戏性能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值