1. 程式人生 > >Unity3D 物件池思想 在遊戲開發中的運用

Unity3D 物件池思想 在遊戲開發中的運用

分類:U3D

1.在王者榮耀中,每30秒小兵會出現一波,出現之後會被敵方玩家或敵方小兵銷燬,一局遊戲下來,小兵會被建立多次,同時也會被銷燬,在遊戲中,這種頻繁的建立和銷燬遊戲物件是很損耗效能的。在遊戲開發過程中,我們會頻繁的建立物件和銷燬物件,為了提高遊戲效能,我們就要用到物件池思想了。

2.在射擊遊戲中,會頻繁的銷燬和建立子彈,這就可以用物件池思想了。

什麼是物件池?

池,想到了水池,水池是水的集合。所以,物件池就是物件的集合,我們可以初步的按照這種想法來理解物件池。使用原理的話就是,我們在建立遊戲物件時,我們就從物件池裡取出來,並設定為可見(Obj.seAactive(true)),要銷燬物件時又把物件放到物件池裡再隱藏(Obj.setActive(false)),以備下次需要從物件池中取物件時使用。

接下來就來看實現過程。

先來說說要實現的效果,我們單機螢幕上的任意一點,然後就可以發射一個子彈(球),並利用物件池對子彈進行儲存,達到優化效能的目標;

首先建立一個指令碼,這個指令碼不用繼承自Mono,並且用單例模式實現。

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

public class GameObjectManage
{
    private List<GameObject> gameobjectlist;   // 儲存物件的集合
    // 不再累述單例模式
    private GameObjectManage()
    {
        gameobjectlist=new List<GameObject>();
    }

    private static  GameObjectManage instance;

    public static GameObjectManage GetInstance
    {
        get
        {
            if (instance == null )
            {
                instance=new GameObjectManage();
            }
            return instance;
        }
    }
    // 建立子彈的方法
    public GameObject Instance_obj(GameObject obj)
    {
        GameObject result;
        if (gameobjectlist.Count > 0)    // 假如集合不為空,就從集合中取出物件
        {
            result = gameobjectlist[0];   // 獲得集合中的第一個物件
            result.SetActive(true);          // 並將其顯示
            gameobjectlist.Remove(result); // 已獲得物件,將這個物件從集合中移除
        }
        else    // 集合為空,無法從池中取物件,得直接建立
        {
            result= MonoBehaviour.Instantiate(obj) ;
        }
        return result;
    }
    // 銷燬子彈的方法(其實是隱藏子彈)
    public void DestroryObj(GameObject obj)
    {
        obj.transform.position=new Vector3(0,0,0);    // 將這個子彈的位置歸零
        obj.SetActive(false);     // 並設定不可見
        gameobjectlist.Add(obj);  // 加入到物件池中,為了下次建立物件時備用
    }

}

然後再建立一個指令碼用來實現建立子彈,把這個指令碼掛載再相機上

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

public class contro : MonoBehaviour
{
    public GameObject obj;
    private Ray _ray;   // 射線
    void Update()
    {
        if (Input.GetMouseButtonDown(0))    
        {
            _ray = Camera.main.ScreenPointToRay(Input.mousePosition);//發射射線
           GameObject gb= GameObjectManage.GetInstance.Instance_obj(obj);
           obj.transform.position = transform.position;
           gb.GetComponent<Rigidbody>().velocity = _ray.direction *100;
        }
        
    }
}

為了可以實現子彈2秒鐘後將其隱藏,我們還需要建立一個指令碼來掛載在子彈預製體上,對了,預製體上還需要加剛體。

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

public class cube_contro : MonoBehaviour
{
    private void OnEnable()    // 不可換成Start哦
    {
        StartCoroutine(WaitDestrory());
    }

    IEnumerator WaitDestrory()    // 協程實現2秒鐘後隱藏
    {
        yield return new WaitForSeconds(2f);
        GameObjectManage.GetInstance.DestroryObj(gameObject);
    }

}

通過這幾個指令碼就可以通過物件池來實現子彈發射效果咯,蠻簡單的,但很使用。

多多思考,舉一反三,將物件池思想用於自己的遊戲中吧!

&n