ゲームオブジェクトを使い回す(2)

ゲームオブジェクトを使い回す(1)からの続きなので、まず(1)を先に進めてください

最初に完成形を見てみましょう

スペースキーを押している間、ずっとオブジェクトを作っています
1秒後、作られたオブジェクトは消滅します

シーンの構成

カメラの位置サンプル

GameObjectアタッチサンプル

PoolManagerアタッチサンプル

Prefabアタッチサンプル

コード

PlayerController

Input.GetKeyメソッドとすることで、キーが押されている間中処理するコードになります

using UnityEngine;

public class PlayerController : MonoBehaviour
{
    [SerializeField]
    PoolManager poolManager;

    void Update()
    {
        if (Input.GetKey(KeyCode.Space))
        {
            GameObject obj = poolManager.Instantiate();
            Show(obj);
        }
    }

    void Show(GameObject obj)
    {
        // 出現させる座標をランダムに設定
        int x = Random.Range(-20, 21);
        int y = Random.Range(-20, 21);
        int z = Random.Range(-20, 21);

        obj.transform.position = new Vector3(x, y, z);
    }
}

PoolManager

ヒエラルキーにたくさんのオブジェクトが作られるのですが、みにくいのでフォルダの中に作っているように見せます
Unityでは親子関係と呼んでいます

次のコードで、親オブジェクトにぶら下がっている子オブジェクトの構成になります

子オブジェクト.transform.SetParent(親のゲームオブジェクト.transform);

親のゲームオブジェクトは、GameObject.Find(“親のゲームオブジェクトの名前")になりますね

子オブジェクト.transform.SetParent(GameObject.Find("親のゲームオブジェクトの名前").transform);

今回は、スクリプトをアタッチしているゲームオブジェクトを親としますので、次のコードでよさそうです

子オブジェクト.transform.SetParent(GameObject.Find(gameObject.name).transform);

コードに反映させましょう

using System.Collections.Generic;
using UnityEngine;

public class PoolManager : MonoBehaviour
{
    List<GameObject> gameObjects = new List<GameObject>();

    [SerializeField]
    GameObject prefab;

    void Awake()
    {
        InitPool();
    }

    public GameObject Instantiate()
    {
        GameObject findObj = gameObjects.Find(obj => !obj.activeInHierarchy);

        if (findObj == null)
        {
            return null;
        }
        // ゲームオブジェクトを有効にする
        findObj.SetActive(true);
        return findObj;
    }

    void InitPool()
    {
        // 最初にゲームオブジェクトを作っておく
        for (int i = 0; i < 1000; i++)
        {
            var obj = Instantiate(prefab);
            // 無効化しておく
            obj.SetActive(false);

            // ヒエラルキーが見辛くなるので親子関係にしておく
            obj.transform.SetParent(GameObject.Find(gameObject.name).transform);

            // リストに追加
            gameObjects.Add(obj);
        }
    }
}

PrefabControl

using System.Collections;
using UnityEngine;

public class PrefabControl : MonoBehaviour
{
    private void OnEnable()
    {
        StartCoroutine(DelayInActive());
    }

    IEnumerator DelayInActive()
    {
        // 1秒待って、その次のコード(SetActiveメソッド)が実行される
        yield return new WaitForSeconds(1);
        gameObject.SetActive(false);
    }
}