U3D自创对象池,GC垃圾回收Dictionary<string,List<GameObject>> pool,prefabs,pool.ContainsKey(objname) 子弹的速度veloc

//*************************************** ** 步骤一 声明两个字典** **************************************//

声明 Dictionary<string,List> pool = new Dictionary<string,List>(); 字典类型的对象池 pool
声明 Dictionary<string,GameObject> prefabs = new Dictionary<string,GameObject>(); 字典类型的预制体池 prefabs

//*************************************** ** 步骤二 获取对象池里的对象** **************************************//
pool.ContainsKey(objName) 判断对象池中是否有objName名字的对象列表List
pool[objName].Count>0 判断对象池中是否有objName名字的对象列表List的长度是否大于0个
pool[objName].Remove(result); 把result结果从对象池中移除

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{ // 如果没有加载过该预设体// 从Resources文件夹中加载预设体
prefab = Resources.Load(“Prefabs/”+objName);
prefabs.Add(objName, prefab);// 把从Resources文件夹加载预设体添加到字典prefabs中
}
//生成
result = UnityEngine.Object.Instantiate(prefab);
//改名(去除 Clone)
result.name = objName;
//返回
return result;

//*************************************** ** 步骤三 回收对象到对象池里面** **************************************//
pool.ContainsKey(obj.name) //判断对象池中是否有objName名字的对象列表List
pool[obj.name].Add(obj); //如果已经存在对象把obj 对象先放到 pool对象池里边的 List 对象池列表里面
pool.Add(obj.name, new List() { obj }); //如果不存在此对象,把这个对象的对象名obj.name 和 对象obj分别放进
对象池pool的(string ,List 的对象列表里边)

public void RecycleObj(GameObject obj){
obj.SetActive(false); //设置为非激活
if (pool.ContainsKey(obj.name)){ //判断是否有该对象的对象池 //放置到该对象池
pool[obj.name].Add(obj); //把obj放到pool[obj.name]对象池的 List中
}else{ //创建该类型的池子,并将对象放入
pool.Add(obj.name, new List() { obj }); //如果没有,自己创建一个放进去
}
}

//对象池

对象池的使用类 挂在在摄像机上
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;   **子弹行进的象形速度  带方向的**
           
        }
    }
}

}

创建对象池的 类 1获取对象池里的对象 2
//对象池代码:
//(不需要挂载)

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

public class ObjectPool {
#region 单例模式
private static ObjectPool instance;
private ObjectPool() //构造函数功能 给字段赋值。声明一个pool
{
pool = new Dictionary<string, List>();//给下面的pool字典赋值
prefabs = new Dictionary<string, GameObject>();//给下面的prefabs字典赋值
}
//单例模式
public static ObjectPool GetInstance()
{
if (instance==null)
{
instance = new ObjectPool();
}
return instance;
}
private Dictionary<string,List> pool; // 对象形字典对象池的声明 字典pool
private Dictionary<string, GameObject> prefabs; // 预制体字典形池的声明 字典prefabs

//从对象池里面获取完之后  ,要从对象池里面移除,才能保证平衡,资源的反复调用
//获取对象  就是从对象池中取出对象,如果没有,就从Resources中Load 该对像
public GameObject GetObj(string objName)      //从对象池中获取对象  的函数
{
    //结果对象
    GameObject result=null;
    //判断是否有该名字的对象池,若有,先pool[objName].Remove(result);清除对象池,保证对象池干净  
    if (pool.ContainsKey(objName))
    {
            //对象池里有对象       
        if (pool[objName].Count>0)
        {
            //获取结果
            result = pool[objName][0];
            //激活对象
            result.SetActive(true);
            //从池中移除该对象
            pool[objName].Remove(result);
            //返回结果
            return result;
        }          
    }
        ## //*****************  **  判断该prefabs字典中是否有名字  ********************************//
    //判断该prefabs字典中是否有名字
    //如果没有  该名字的对象池  或者 该名字对象池 没有对象
    GameObject prefab = null;      
    if (prefabs.ContainsKey(objName))   //如果已经加载过该预设体,就把这个预制体加载出来
    {
        prefab = prefabs[objName];      
    }
    else                                      // 如果没有加载过该预设体// 从Resources文件夹中加载预设体
    {          
        prefab = Resources.Load<GameObject>("Prefabs/"+objName); 
        prefabs.Add(objName, prefab);// 把从Resources文件夹加载预设体添加到字典prefabs中
    }
  
    //生成
    result = UnityEngine.Object.Instantiate(prefab);
    //改名(去除 Clone)
    result.name = objName;
    //返回
    return result;
}

## //*****************  **回收对象到对象池    就是往对象池里面添加对象     ***********************************//
public void RecycleObj(GameObject obj)
{
    obj.SetActive(false);                          //设置为非激活
    if (pool.ContainsKey(obj.name))     //判断是否有该对象的对象池
    {       
        //放置到该对象池
        pool[obj.name].Add(obj);   //把obj放到pool[obj.name]对象池的 List<GameObject>中
    }
    else
    {
        //创建该类型的池子,并将对象放入
        pool.Add(obj.name, new List<GameObject>() { obj }); //如果没有,自己创建一个放进去
    }
    }

}

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

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>

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

IEnumerator AutoRecycle()
{
    yield return new WaitForSeconds(3f);                            //携程等待3秒
    ObjectPool.GetInstance().RecycleObj(gameObject);//调用 对象池类的RecycleObj方法回收对象
}

}

例二

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

public class ObjectPool
{
public const string stoneExplosion = “done_explosion_asteroid”;
public const string enemyExplosion = “done_explosion_enemy”;
public const string playerExplosion= “done_explosion_player”;
public const string redStone = “Asteroid_Lrg_B_01”;
public const string boss1 = “Boss1”;
public const string shuijing = “Crystal_Lrg_A_01”;
public const string blackStone = “Done_Asteroid 02”;
public const string playerAttack = “Done_Bolt”;
public const string enemyAttack = “Done_Bolt-Enemy”;
public const string player = “Done_Player”;
public const string purpleEnemy = “Done_PurpleEnemy”;
public const string redEnemy = “Done_RedEnemy”;

/// <summary>
/// 对象池
/// </summary>
private Dictionary<string, List<GameObject>> pool;

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


/// <summary>
/// 从对象池中获取对象
/// </summary>
/// <param name="objName"></param>
/// <returns></returns>
public GameObject GetObj(string objName,Vector3 position,Quaternion quaternion)
{
    //结果对象
    GameObject result = null;
    //判断是否有该名字的对象池
    if (pool.ContainsKey(objName))
    {
        //对象池里有对象
        if (pool[objName].Count > 0)
        {
            //获取结果
            result = pool[objName][0];
            //激活对象
            result.transform.position = position;
            result.transform.rotation = quaternion;
            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 = Object.Instantiate(prefab);
    result.transform.position = position;
    result.transform.rotation = quaternion;
    //改名(去除 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 });
    }

}

}

原文链接:https://blog.csdn.net/qq_15020543/article/details/82933479

//垃圾回收

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值