Unity对象池 垃圾回收机制

时光毁灭记忆、已成空白 提交于 2019-12-02 06:19:30

//对象池

对象池的使用类 挂在在摄像机上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class GameController : MonoBehaviour {
public int row = 6;
public Vector2 offset = new Vector2();
public GameObject cubPrefab;
public GameObject bulletPrefab;
private RaycastHit hit;
public float speed=3;
void Start () {
//生成墙
for (int i = 0; i < row; i++)
{
for (int j= 0; j < row; j++)
{
Instantiate(cubPrefab, new Vector3(i, j, 0)+new Vector3(offset.x,offset.y,0),
Quaternion.identity);
}
}
}

// Update is called once per frame
void Update () {
    if (Input.GetMouseButtonDown(0))
    {
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
        if (Physics.Raycast(ray,out hit))
        {
            Vector3 dir = hit.point - Camera.main.transform.position;
            //从对象池中获取对象
            GameObject bullet = ObjectPool.GetInstance().GetObj("Bullet");
            bullet.transform.position = Camera.main.transform.position;
            bullet.GetComponent<Rigidbody>().velocity = dir.normalized * speed;
           
        }
    }
}

}

对象池的创建类
//对象池代码:
//(不需要挂载)

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

public class ObjectPool {
#region 单例
private static ObjectPool instance;
private ObjectPool()
{
pool = new Dictionary<string, List>();
prefabs = new Dictionary<string, GameObject>();
}
public static ObjectPool GetInstance()
{
if (instance==null)
{
instance = new ObjectPool();
}
return instance;
}

#endregio
/// <summary>
/// 对象池
/// </summary>
        private Dictionary<string,List<GameObject>> pool;
/// <summary>
/// 预设体
/// </summary>
        private Dictionary<string, GameObject> prefabs;
/// <summary>
/// 从对象池中获取对象
/// </summary>
/// <param name="objName"></param>
/// <returns></returns>
public GameObject GetObj(string objName)
{
    //结果对象
    GameObject result=null;
    //判断是否有该名字的对象池
    if (pool.ContainsKey(objName))
    {
            //对象池里有对象
        if (pool[objName].Count>0)
        {
            //获取结果
            result = pool[objName][0];
            //激活对象
            result.SetActive(true);
            //从池中移除该对象
            pool[objName].Remove(result);
            //返回结果
            return result;
        }          
    }
    //如果没有该名字的对象池或者该名字对象池没有对象

    GameObject prefab = null;      
    //如果已经加载过该预设体
    if (prefabs.ContainsKey(objName))
    {
        prefab = prefabs[objName];
    }
    else     //如果没有加载过该预设体
    {
        //加载预设体
        prefab = Resources.Load<GameObject>("Prefabs/"+objName);
        //更新字典
        prefabs.Add(objName, prefab);
    }
  
    //生成
    result = UnityEngine.Object.Instantiate(prefab);
    //改名(去除 Clone)
    result.name = objName;
    //返回
    return result;
}

/// <summary>
/// 回收对象到对象池
/// </summary>
/// <param name="objName"></param>
public void RecycleObj(GameObject obj)
{
    //设置为非激活
    obj.SetActive(false);
    //判断是否有该对象的对象池
    if (pool.ContainsKey(obj.name))
    {       
        //放置到该对象池
        pool[obj.name].Add(obj);
    }
    else
    {
        //创建该类型的池子,并将对象放入
        pool.Add(obj.name, new List<GameObject>() { obj });
    }
    }
void Start () {  
} 
// Update is called once per frame
void Update () { 
}

}

挂载在子弹上,自动回收到对象池的代码:

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

public class Bullet : MonoBehaviour {

// Use this for initialization
void Start () {
    
}

// Update is called once per frame
void Update () {
    
}

/// <summary>
/// 3秒后自动回收到对象池
/// </summary>
/// <returns></returns>
IEnumerator AutoRecycle()
{
    yield return new WaitForSeconds(3f);
   
    ObjectPool.GetInstance().RecycleObj(gameObject);
}

private void OnEnable()
{
    StartCoroutine(AutoRecycle());
}

}

//垃圾回收

就是资源的回收,资源的声明周期就是 1声明 2赋值 3使用 4销毁 一般clear remove

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!