LoginSignup
0
0

More than 1 year has passed since last update.

TD 敵のスポーン機能を実装 2/2:ObjectPoolを使って実装

Last updated at Posted at 2023-03-27

概要

今回はデザインパターンのObjectPoolを使って、敵のスポーンを管理します。
ObjectPoolを使うことでゲームオブジェクトの生成、削除する回数が少なくなりパフォーマンスが向上します。
以下gifのような動きを実現します。
1秒毎にPool配下の子オブジェクトが活性化されています。ゲーム的には1秒毎に敵がスポーンされているという意味です。

Spwan1111.gif

開発環境

IDE:Rider
Unity:2020.3.42(LTS)
OS:Windows10

実装の方針

従来:Objectの有無(CreateInstanceとDestor)で敵のスポーンを管理
今回:あらかじめ生成されるオブジェクトを全て生成し、GameObject.setActive(true or false)で敵のスポーンの有無を表現する。

コード

ObjectPooler.cs
using System.Collections.Generic;
using UnityEngine;

public class ObjectPooler : MonoBehaviour
{
    [SerializeField] private GameObject prefab;
    [SerializeField] private int poolSize;
    
    private List<GameObject> _pool;
    private GameObject _poolContainer;

    private void Awake()
    {
        _pool = new List<GameObject>();
        _poolContainer = new GameObject($"Pool - {prefab.name}");
        CreatePooler();
    }

    private void CreatePooler()
    {
        for (int i = 0; i < poolSize; i++)
        {
            _pool.Add(CreateInstance());
        }
    }
    
    private GameObject CreateInstance()
    {
        GameObject newInstance = Instantiate(prefab);
        newInstance.transform.SetParent(_poolContainer.transform);
        newInstance.SetActive(false);
        return newInstance;
    }

    // 
    public GameObject GetInstanceFromPool()
    {
        for (int i = 0; i < _pool.Count; i++)
        {
            if (!_pool[i].activeInHierarchy)
            {
                return _pool[i];
            }
        }
        // poolの数がいっぱいの場合は空のGameObjectを返す。
        return CreateInstance();
    }
}
Spawner.cs
using System;
using UnityEngine;


    public class Spawner : MonoBehaviour
    {
-        [SerializeField] private GameObject testGO;
        [SerializeField]  private  int enemyCount = 10;
        // Btw = Between
        [SerializeField] private float delayBtwSpawns;

        private int _enemiesSpawned;
        private float _spawnTimer;
+        private ObjectPooler _objectPooler;

        private void Start()
        {
            _objectPooler = GetComponent<ObjectPooler>();
        }

        private void Update()
        {
            _spawnTimer -= Time.deltaTime;
            if (_spawnTimer < 0)
            {
                _spawnTimer = delayBtwSpawns;
                if (_enemiesSpawned < enemyCount)
                {
                    SpawnEnemy();
                    _enemiesSpawned++;
                }
            }
        }
        
        private void SpawnEnemy()
        {
+            GameObject newInstance = _objectPooler.GetInstanceFromPool();
+            newInstance.SetActive(true);
        }
        
    }


参考

SetActive

image.png

$ を使う文字列補間

image.png

UnityでObjectPoolのクラスが実装されている模様

Section3 9 ObjectPooler

github コミット分

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0