오브젝트 풀링

YongSeok·2022년 11월 28일
0
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class PoolInfo
{
    public string       name;       // 만들 애 이름
    public GameObject   prefab;     // 프리팹
    public int          amount;     // 몇개
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Pool
{
    public Transform root { get; protected set; }      // Transform parentTransform = new GameObject(current.name).transform; 계층구조 깔끔하게 만들게 해준 애
    public GameObject prefab { get; protected set; }    // 공이랑 큐브

    // 현재 대기중인 오브젝트 (꺼져있는 애들), 켜지기위해서 대기중인애들
    protected Queue<GameObject> objects = new Queue<GameObject>();


    public Pool(Transform wantRoot, GameObject wantPrefab)
    {
        root = wantRoot;
        prefab = wantPrefab;
    }

    public GameObject Create()
    {
        GameObject target;   // 큐에서 뺀다

        if (objects.Count <= 0)
        {
            CreateNewInstance();
        }
        target = objects.Dequeue();
        target.SetActive(true); // 켜서

        
        target.BroadcastMessage("PoolInitialize");//???
        return target;  // 돌려줌
    }

    
    public GameObject CreateNewInstance()
    {
        // 만들어서
        GameObject inst = GameObject.Instantiate(prefab, root);

        // 혹시 이미 있니?
        PoolComponent poolCompo = inst.GetComponent<PoolComponent>();
        if(poolCompo == null)
        {
            poolCompo = inst.AddComponent<PoolComponent>();
        }
        poolCompo.myPool = this;
        // 꺼버림
        inst.SetActive(false);

        objects.Enqueue(inst);  // 큐에다 넣어준다
        return inst;
    }

    public void Delete(GameObject target)
    {
        target.SetActive(false);    // 타겟을 꺼주고
        objects.Enqueue(target);    // 큐에 넣어준다
    }
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PoolManager : MonoBehaviour
{
    public PoolInfo[] infos;    // info들 많을꺼니까
    static Dictionary<string, Pool> poolDictionary = new Dictionary<string, Pool>();

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            Create("공").transform.position = Random.insideUnitSphere * 5;
        }
        if (Input.GetKeyDown(KeyCode.S))
        {
            Create("큐브").transform.position = Random.insideUnitSphere * 5;
        }
        if(Input.GetMouseButtonDown(0))
        {

            Ray cameraRay = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            Physics.Raycast(cameraRay, out hit);
            if (hit.collider != null)
            {
                Delete(hit.collider.gameObject);
            }

        }
    }

        // 만든친구들을 기억해야한다
    void Start()
    {
        Load();
    }

    public static void Delete(GameObject target)
    {
        PoolComponent poolCompo = target.GetComponent<PoolComponent>();
        if(poolCompo)
        {
            Pool targetPool = poolCompo.myPool;

            if(targetPool != null)
            {
                targetPool.Delete(target);
            }
            else
            {
                Destroy(target);
            }
        }
        else
        {
            Destroy(target);
        }
        
    }
    public static GameObject Create(string wantName)
    {
        Pool targetPool;
        // 해당하는 이름의 풀이 있는지 확인 있으면 true  // 있으면 여기(targetPool)에 넣어줘!
        if(poolDictionary.TryGetValue(wantName, out targetPool))
        {
            return targetPool.Create();
        }
        return null;
    }
    public void Load()
    {
        foreach(var current in infos)
        {
            // 풀을 일단 만들고
            Pool currentPool = new Pool(new GameObject(current.name).transform, current.prefab);

            // 사전에 등록
            poolDictionary.Add(current.name, currentPool);

            // 처음에 만들기!
            for(int i = 0; i < current.amount; i++)
            {
                currentPool.CreateNewInstance();
            }
        }
    }
}

0개의 댓글

관련 채용 정보