第29天动态加载、对象池

资源动态加载

加载资源:将资源从硬盘中加载到内存中

常见的资源:预制体,图片 ,音频,文本,脚本

资源加载方式

克隆

只能加载预制体

直接使用Instantiate克隆预制体,每次克隆都需要从硬盘加载到内存,比较消耗性能。

动态加载

动态加载

Resources.Load

将资源直接加载到内存中,省去了每次从硬盘加载到内存的过程

节省了时间,消耗了空间

方法

在Assets下创建Resources文件夹(区分大小写),只能加载Resources文件夹下的资源

Resources.Load("相对路径"):不用写Resources 不用写后缀名

Resources.LoadAll

加载一个文件夹下的所有资源,包括子文件夹

泛型:只会加载制定类型的资源

对象池(缓冲池)

作用

管理游戏中需要频繁创建和销毁的物体,避免大量使用Instantiate和Destroy

优点

以空间换时间

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

public class ObjectPools : AutoSingle<ObjectPools>
{

    private Dictionary<string, List<GameObject>> poolDic = new Dictionary<string, List<GameObject>>();

   
    public GameObject GetObject(string objName)
    {
        GameObject obj = null;                      //创建空指向物体用来接收查找到的数据
        //List<GameObject> pool = null;               //创建一个空的小池子
        //if(poolDic.TryGetValue(objName,out pool))   //利用字典的TryGetValue方法,如果有则返回该值
        //{
        //    if(pool.Count>0)                        //判断池子是否有数据
        //    {
        //        obj = pool[0];                      //如果有数据获取第一条
        //        pool.RemoveAt(0);                   //池子中删除该物体的数据
        //    }
        //}
        if(poolDic.ContainsKey(objName))
        {
            if(poolDic[objName].Count>0)
            {
                obj = poolDic[objName][0];
                poolDic[objName].RemoveAt(0);
            }
        }
        if(obj==null)                               //如果此时还是null 则证明没有池子或者池子中没有数据,那么需要加载资源
        {
            GameObject prefab = Resources.Load<GameObject>("MyPrefabs/" + objName);     //加载该物体
            obj = Instantiate(prefab);                                                  //克隆物体
            obj.name = objName;                                                         //主要是为了删去(clone)
        }
        obj.SetActive(true);                                                            //激活物体
        obj.transform.SetParent(null);                                                  //父物体设为null
        return obj;
    }


    /// <summary>
    /// 重载获取方法
    /// </summary>
    /// <param name="objName"></param>
    /// <param name="position"></param>
    /// <param name="rotation"></param>
    /// <returns></returns>
    public GameObject GetObject(string objName, Vector3 position, Quaternion rotation)
    {
        return GetObject( objName,  position,  rotation, null);
    }
    /// <summary>
    /// 重载获取方法并设置父物体
    /// </summary>
    /// <param name="objName"></param>
    /// <param name="position"></param>
    /// <param name="rotation"></param>
    /// <param name="parent"></param>
    /// <returns></returns>
    public GameObject GetObject(string objName,Vector3 position, Quaternion rotation, Transform parent)
    {
        Debug.Log(objName);
        GameObject obj = GetObject(objName);                //获取物体
        obj.transform.position = position;                  //设置坐标
        obj.transform.rotation = rotation;                  //设置旋转度
        obj.transform.SetParent(parent);                    //设置父物体
        return obj;
    }
    public void RecycleObject(GameObject obj)
    {
        List<GameObject> pool = null;
        if(!poolDic.TryGetValue(obj.name, out pool) )       //判断如果没有获取到数据
        {
            pool = new List<GameObject>();                  //没有池子先实例一个列表
            //字典的两种添加方式  
            //第一种是 Add(键,值) 如果有重复的键则会报错
            //第二种是 字典名[键] = 值   如果没有则创建 如果存在则修改
            poolDic[obj.name] = pool;
        }
        pool.Add(obj);                                      //添加到池子中
        obj.SetActive(false);                               //失活
        obj.transform.SetParent(transform);                 //设置父物体
        
    }

}
原文地址:https://www.cnblogs.com/yifengs/p/14237417.html