Pool Manager & Game Manager - TeamCrazyPerformance/Game_study GitHub Wiki

Object Pooling

  • Object를 필요할 때마다 Pool이라는 공간에서 꺼내와서 사용하는 기법입니다.
  • Object를 생성/삭제할 때 마다 GC(Garbage Collection)가 발생하는데, 이는 CPU에 부담을 주게 됩니다.
  • 초기 메모리를 미리 지정해두고 그 안에서 Object를 관리함으로써 게임 성능을 향상시킬 수 있습니다.

Pool Manager

  • 처음 시작시 일정량의 Object를 생성하여 Pool에 저장합니다.
  • Object를 필요할 때마다 활성화해 pool에서 꺼내고 사용이 끝난 뒤엔 비활성화해 다시 pool에 저장하는 방식입니다.

List를 사용한 object pool 구현


/* Unity - Introduction to Object Pooling */
public static ObjectPool SharedInstance;
public List pooledObjects;
public GameObject objectToPool;
public int amountToPool;

void Awake()
{
    SharedInstance = this;
}

void Start() 
{
    pooledObjects = new List(); // pool 생성
    GameObject tmp; 
    for(int i = 0; i < amountToPool; i++) // amountToPool만큼 object 생성
    {
        tmp = Instantiate(objectToPool);
        tmp.SetActive(false);
        pooledObjects.Add(tmp);
    }
}

public GameObject GetPooledObject() // object를 pool에서 꺼내오는 함수
{
    for(int i = 0; i < amountToPool; i++) // List 앞부분부터 차례대로 검색
    {
        if(!pooledObjects[i].activeInHierarchy) // 맨 앞에 있는 오브젝트부터 반환
        {
            return pooledObjects[i];
        }
    }
    return null;
}
/* 설명에선 pool에 다시 넣을 땐 SetActive(false); 를 통해 deactive 한다고 쓰여있음 */
/* List를 검색해서 꺼내오는 방식보단 Stack을 이용한 구현방식이 더 효율적일 듯? */

  • Unity에서도 2021년 이후 자체적으로 Object Pooling을 지원해주고 있습니다.

ObjectPool objectPool = new ObjectPool(CreateObject,
                OnGetFromPool, OnReleaseToPool, OnDestroyPooledObject,
                collectionCheck, defaultCapacity, maxSize); 
// 오브젝트 생성, 초기화, 활성화, 제거, 예외처리, 기본크기, 최대크기 지정

GameManager

  • 게임의 점수, 승패 조건 등 게임의 전반적인 흐름을 담당합니다.
  • Unity에서 "GameManager" 라는 스크립트를 만들면 자동으로 톱니바퀴 모양으로 변하게 됩니다.

image

예시

  • 고등학교 때 만들었던 게임을 Game Manager로 정리해보았습니다.
  • 게임의 UI나 전반적인 기능을 많은 스크립트로 작성했는데, 이를 Game Manager로 한 번에 표현할 수 있습니다.

image

image


/* GameManager를 활용한 배터리 및 폭죽 UI 구현 */
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class GameManager : MonoBehaviour
{
    /* 배터리 부분 변수 */
    public static bool onoff; // true : 켜짐 / false : 꺼짐
    public GameObject Target; // 손전등 불빛 오브젝트
    public static bool click; // ?
    private Image battery;
    public Sprite[] sprites;
    public int MaxTime = 120;
    public static float time = 0;

    /* 폭죽 UI 변수 */
    int fireworkCount;
    public GameObject[] Fireworks = new GameObject[3];

    void Start()
    {
        SetBattery();
    }

    // Update is called once per frame
    void Update()
    {
        UpdateBattery();
        UpdateFirework();
    }

    void SetBattery()
    {
        time = MaxTime;
        battery = GetComponent();
        onoff = false;
        Target.SetActive(false);
    }

    void UpdateBattery()
    {
        /* 배터리 비율에 따른 UI 변경 */
        if (time >= MaxTime * 0.8)
            battery.sprite = sprites[0];
        else if (time >= MaxTime * 0.6)
            battery.sprite = sprites[1];
        else if (time >= MaxTime * 0.4)
            battery.sprite = sprites[2];
        else if (time >= MaxTime * 0.2)
            battery.sprite = sprites[3];
        else if (time > 0)
            battery.sprite = sprites[4];
        else
            battery.sprite = sprites[5];

        /* 손전등 배터리 소모 */
        if (onoff && time > 0)
            time -= Time.deltaTime;
        else if (time < 0) // 배터리 없으면 꺼지도록
        {
            time = 0;
        }
        if (Input.GetKeyDown(KeyCode.F) || click) // 손전등 on/off 변경 확인
        {
            onoff = !onoff;
            Target.SetActive(onoff);
            click = false;
        }
    }

    void UpdateFirework()
    {
        fireworkCount = Player.firework_Count;

        if (fireworkCount > 0)
        {

            Fireworks[0].gameObject.SetActive(true);
            Fireworks[1].gameObject.SetActive(false);

            if (fireworkCount > 1)
            {
                Fireworks[1].gameObject.SetActive(true);
                Fireworks[2].gameObject.SetActive(false);
            }

            if (fireworkCount > 2)
                Fireworks[2].gameObject.SetActive(true);
        }
        else
        {
            Fireworks[0].gameObject.SetActive(false);
            Fireworks[1].gameObject.SetActive(false);
            Fireworks[2].gameObject.SetActive(false);
        }
    }
}

23 김정완

⚠️ **GitHub.com Fallback** ⚠️