對象池的實現------基於Unity,模擬創建子彈


  最近閑來無事,利用空余時間寫了一個對象池。

  首先,什么是對象池呢?

  舉一個例子。在我們玩FPS類型的游戲的時候(這里就舉例《守望先鋒吧》),點擊鼠標左鍵便會進行射擊,會“創建”出子彈。而此時,隨着游戲的不斷進行(如果一局進行了20分鍾),便會“創建”成千上萬顆子彈,如果我們每點擊一下鼠標就New一個對象,我想,不管是多牛B的電腦恐怕也吃不消。所以,我們需要一個對象池來進行對象的管理。

圖示:

A.接下來,我們來實現代碼。

1.創建對象池腳本 “GameObjectManager.cs”

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

//存儲對象的名字
public class GameObjectName
{
    public static string g_ButtleName = "g_Buttle";
}

//碰撞標簽
public class Tags
{
    public static string g_Wall = "Wall";
}

public class GameObjectManager : MonoBehaviour
{
    //簡單單例:“粗制濫造型”
    public static GameObjectManager _Instance;

    //字典
    public Dictionary<string, List<GameObject>> m_dic;

    void Awake()
    {
        _Instance = this;
        m_dic = new Dictionary<string, List<GameObject>>();
    }

    void Start ()
    {
        //1.初始化子彈的表
        Debug.Log("初始化 子彈");
        GameObject go = GameObject.Instantiate(Resources.Load("Prefabs/g_Buttle")) as GameObject;
        Init(GameObjectName.g_ButtleName, go);

    }

    //初始化對象池里面的某個對象
    public void Init(string _name, GameObject go)
    {
        List<GameObject> m_list = new List<GameObject>();
        m_list.Add(go);
        m_dic.Add(_name, m_list);
        go.SetActive(false);
    }

    //得到對象
    public GameObject GetGameObjectInDic(string _name)
    {
        string str = "Prefabs/" + _name;
        //如果存在
        if (m_dic.ContainsKey(_name))
        {
            for (int i = 0; i < m_dic[_name].Count; ++i)
            {
                if (!m_dic[_name][i].activeSelf)
                {
                    m_dic[_name][i].SetActive(true);
                    return m_dic[_name][i];
                }
            }

            GameObject go1 = GameObject.Instantiate(Resources.Load(str)) as GameObject;
            m_dic[_name].Add(go1);
            return go1;

        }
       
        GameObject go2 = GameObject.Instantiate(Resources.Load(str)) as GameObject;
        Init(_name, go2);
        return go2;       
    }
}

 

2.讓子彈運行起來,在子彈的Prefab中綁定該腳本,ButtleRun.cs

using UnityEngine;
using System.Collections;

public class ButtleRun : MonoBehaviour
{
    //子彈的運行速度
    private float m_buttleSpeed = 10.0f;
    void Start ()
    {
    
    }
    
    // Update is called once per frame
    void Update ()
    {
        //子彈跑起來
        GameButtleRun();
    }
    void OnTriggerEnter(Collider other)
    {
        Debug.Log("觸碰");
        if (other.gameObject.CompareTag(Tags.g_Wall))
        {
            gameObject.SetActive(false);
        }
    }

    void GameButtleRun()
    {
        transform.position += transform.forward * m_buttleSpeed * Time.deltaTime;
    }
}

 

3.創建子彈的腳本,點擊鼠標左鍵,生成子彈 CreateButtle

using UnityEngine;
using System.Collections;

public class CreateButtle : MonoBehaviour
{
   
    
    void Start ()
    {
    
    }
    
    // Update is called once per frame
    void Update ()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Debug.Log("創建子彈");
            //得到子彈
            GameObject buttle = GameObjectManager._Instance.GetGameObjectInDic(GameObjectName.g_ButtleName);
            buttle.transform.position = GameObject.Find("Gun/Position").transform.position;
            //buttle.transform.position += GameObjectManager._Instance.m_dic[GameObjectName.g_ButtleName][i].transform.forward * buttleSpeed * Time.deltaTime;
        }
    }
}

 

B.Unity場景中的效果

1.點擊鼠標左鍵,創建子彈

 

2.碰撞到牆面,子彈“消失”

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM