萌熊跑酷学习(一)资源池的实现

1.创建工程

工程结构
在这里插入图片描述

2.接口和对象池物体的基类实现

定义一个接口,用来实现对象池中物体的回收、生成。

在这里插入图片描述
定义一个方法,所有的对象池中所挂载脚本的基类。继承自MonoBehaviour和IReusable,并实现这个接口。

在这里插入图片描述

3.实现对象池中子池子的编写

首先创建一个脚本,取名为SubPool。

  • 创建一个LIst集合,用来保存所有属于该池子的所有物体。
  • 创建一个GameObject类型的Prefab
  • 创建一个string类型的名字属性,总的池子会根据这个名字查找对应的子池子。
  • 创建一个Transform类型的父物体的位置,用来设置新生成池子的位置。

创建构造方法,参数为一个Transform和GameObject类型,让字段中的预制和父物体分别等于这两个参数。

创建取出物体方法,创建一个空的临时变量,,遍历List集合,如果当前集合中的有物体的active为false,则把这个物体赋值给临时变量。遍历完毕以后,判断这个临时变量是否为空,如果为空,则创建一个出来,加入到List中。把创建出来的active设置为true,发送一条调用OnSpawn的方法,返回这个临时变量。

创建取出物体的方法,参数为一个要取出的GameObject类型。判断这个物体是否存在List集合中,如果存在,发送一条调用UnSpawn的方法,并把这个物体设置为false。

创建取出所有物体方法,遍历List集合,调用取出物体的方法。

最后,创建判断一个物体是否存在List集合的方法,使用Contains进行判断。

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

/// <summary>
/// 对象池中的子池子
/// 每一个子池子是一个类型
/// </summary>
public class SubPool : MonoBehaviour
{
    /// <summary>
    /// 存储改子池子中的所有物体
    /// </summary>
    List<GameObject> m_objects = new List<GameObject>();

    /// <summary>
    /// 预制,池子中的类型
    /// </summary>
    GameObject m_Prefab;

    /// <summary>
    /// 父物体的信息
    /// </summary>
    Transform m_Parent;

    /// <summary>
    /// 总池子根据名字来查找子池子
    /// </summary>
    public string Name
    {
        get { return m_Prefab.name; }
    }

    /// <summary>
    /// 构造方法
    /// </summary>
    /// <param name="parent"></param>
    /// <param name="go"></param>
    public SubPool(Transform parent, GameObject go)
    {
        m_Prefab = go;
        m_Parent = parent;
    }

    /// <summary>
    /// 取得物体的方法
    /// </summary>
    /// <returns></returns>
    public GameObject OnSpawn()
    {
        GameObject go = null;

        foreach (var item in m_objects)//判断集合中是否有物体为隐藏状态(隐藏——可用),如果有就赋值给go
        {
            if (!item.activeSelf)
            {
                go = item;
            }
        }
        if (go == null)//经过遍历以后,说明集合为空或者集合中没有可用的物体,就创建出来,添加到集合中
        {
            go = GameObject.Instantiate<GameObject>(m_Prefab);
            go.transform.parent = m_Parent;
            m_objects.Add(go);
        }
        go.SetActive(true);
        go.SendMessage("OnSpawn", SendMessageOptions.DontRequireReceiver);
        return go;
    }
    /// <summary>
    ///回收单个物体
    /// </summary>
    /// <param name="go"></param>
    public void UnSpawn(GameObject go)
    {
        if (Contain(go))
        {
            go.SendMessage("OnUnSpawn", SendMessageOptions.DontRequireReceiver);
            go.SetActive(false);
        }
    }

    /// <summary>
    /// 回收所有的物体
    /// </summary>
    public void UnSpawnAll()
    {
        foreach (var item in m_objects)
        {
            UnSpawn(item);
        }
    }
    /// <summary>
    /// 物体是否存在池子中
    /// </summary>
    /// <param name="go"></param>
    /// <returns></returns>
    public bool Contain(GameObject go)
    {
        return m_objects.Contains(go);      
    }
}

资源池的实现

创建脚本取名为ObjectPool;

  • 创建一个string类型的字段,当作资源目录,和名字组成,生成新的池子。
  • 创建一个字典,key为string,Value为SubPool,string为名字。

创建取出物体的方法,参数为:name(名字),Transform(父物体的位置)。创建一个SubPool的临时变量,判断字典中是否存在参数中的名字,如果不存在,就调用创建新的池子的方法,如果取在,就根据参数名字找到字典中对应的Value赋值给临时变量,返回临时变量。

创建新池子的方法,参数为:name(名字),Transform(父物体的位置)。定义一个string类型的变量path,来当作Resources加载的的路径,path就等于开始时定义的一个string类型的字段加上"/"在加上name。使用Resource创建出这个物体,调用SubPool中的构造方法,把使用Resource创建后的物体传进去。加入到字典当中。回收单个物体和全部回收和子池子是一样的,这里就不写了直接把代码上来。

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

public class ObjectPool : MonoSingleton<ObjectPool>
{
    /// <summary>
    /// 资源目录
    /// </summary>
    public string ResourcesDir;

    /// <summary>
    /// 存储所有的子池子
    /// string为名字
    /// </summary>
    Dictionary<string, SubPool> m_pools = new Dictionary<string, SubPool>();


    /// <summary>
    /// 取出物体
    /// </summary>
    /// <param name="name">子池子的名字</param>
    /// <param name="parent">父物体的位置信息</param>
    /// <returns></returns>
    public GameObject Spawn(string name, Transform parent)
    {
        SubPool pool = null;
        if (!m_pools.ContainsKey(name))//判断池子是否存在 不存在就创建,存在就调用该池子中取出物体的方法
        {
            //生成新的池子
            RegieterNew(name,parent);
        }
        pool = m_pools[name];


        return pool.OnSpawn();
    }

    /// <summary>
    /// 回收单个物体
    /// </summary>
    /// <param name="go">要取出的物体</param>
    public void Unspwan(GameObject go)
    {
        SubPool pool = null;
        foreach (var item in m_pools.Values)//遍历所有的子池子,调用子池子中判断物体是否存在的方法
        {
            if (item.Contain(go))//存在:就调用这个池子中的回收方法
            {
                pool = item;
                break;
            }
        }
        pool.UnSpawn(go);
    }


    /// <summary>
    /// 回收所有的物体
    /// </summary>
    public void UnspawnAll()
    {
        foreach (var item in m_pools.Values)//遍历所有的子池子,调用子池子中判断物体是否存在的方法
        {
            item.UnSpawnAll();//存在:就调用这个池子中的回收所有的方法
        }
    }

    /// <summary>
    /// 创建新的池子
    /// </summary>
    void RegieterNew(string name,Transform parent)
    {
        //资源目录
        string path = ResourcesDir + "/" + name;
        //生成物体
        GameObject go = Resources.Load<GameObject>(path);
        //生成池子
        SubPool pool = new SubPool(parent,go);
        m_pools.Add(pool.Name,pool);
    }
}

下面是我的微信公众号,可以关注一下,问我拿一些学习视频。

在这里插入图片描述
本人正在学习中,如果有错误欢迎各位大佬提携提携小弟,感激不尽!!!

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值