본문 바로가기
게임 개발

[Unity] BrickOutGame - 오브젝트 풀링 (2)

by chobbo 2024. 5. 17.

 

오늘은 오브젝트 풀링을 이용한 레벨 디자인을 진행했다.

오늘까지의 벽돌깨기 게임

 

ObjectPool 배열 안에 36개의 게임 오브젝트들을 미리 선언해두고

레벨 별 Json 데이터를 읽어와 스테이지 별로 Pool 배열 안의 벽돌 데이터를 설정해주었다.

 

BrickData

[System.Serializable]
public class BrickData
{
    public int HP;
    public int Score;
    public bool IsActive;
}

[System.Serializable]
public class BrickDataList
{
    public BrickData[] bricks;
}

 

다음과 같은 형태로 BrickData 선언

 

"bricks": [
  {
    "HP": 10,
    "Score": 10,
    "IsActive": true
  }
  .
  .
  .
  ]

 

작성한 Json 데이터 형태. 36개 다 일일히 적어주려니 길이가 너무 길고,

관리나 수정이 어려워 보였다.

-> Json 데이터의 양이 너무 길어져 Brick Type을 8~10개 정도로 나누어

    Json 데이터에 타입 하나만 넣도록 바꾸어 줄 예정!

 

 

ObjectPoolManager

using System.Collections.Generic;
using UnityEngine;

public class ObjectPoolManager : MonoBehaviour
{
    [SerializeField] private GameObject brickObj;
    [SerializeField] public GameObject[,] pool = new GameObject[6,6];

    private void Awake()
    {
        SpawnPool();
    }

    private void SpawnPool()
    {
        float posX = -2.75f;
        float posY = 3f;

        for (int i = 0; i<6; i++)
        {
            for (int j = 0; j<6; j++)
            {
                GameObject brick = Instantiate(brickObj);
                brick.transform.SetParent(gameObject.transform, false);
                brick.transform.position = new Vector2(posX, posY);
                pool[i, j] = brick;
                posX += 1.1f;
            }
            posX = -2.75f;
            posY -= 0.5f;
        }
    }

    public void EnableObj(GameObject obj)
    {
        obj.SetActive(true);
    }
    public void DisableObj(GameObject obj)
    {
        obj.SetActive(false);
    }
}

 

ObjectPoolManager 스크립트에서는 

게임이 실행되었을 때 ObjectPool내에 36개의 벽돌을 생성해주는 역할이다.

 

LevelDataManager

using System.IO;
using UnityEditor.EditorTools;
using UnityEngine;

public class LevelDataManager : MonoBehaviour
{
    private ObjectPoolManager poolManager;
    private BrickDataList brickDataList;

    private void Awake()
    {
        poolManager = GetComponent<ObjectPoolManager>();    
    }
    private void Start()
    {
        LoadData();
        LevelPoolSpawn();
    }
}

 

레벨 데이터 매니저에서는 실질적인 데이터를 각각의 벽돌에 넣어준다.

private void LoadData()
{
    string filePath = Path.Combine(Application.streamingAssetsPath, $"level{GameManager.Instance.stageNum}.json");
    if (File.Exists(filePath))
    {
        string dataAsJson = File.ReadAllText(filePath);
        brickDataList = JsonUtility.FromJson<BrickDataList>(dataAsJson);
    }
}

 

LoadData() 함수에서는 Assets > steamingAssetPath 폴더 내의 Json 폴더를 읽어온다.

만약 파일이 존재한다면 brickDataList라는 BrickDataList에 Json 폴더 내의 값을 저장한다.

 

private void LevelPoolSpawn()
{
    int idx = 0;
    for (int i = 0; i < 6; i++)
    {
        for(int j = 0;j < 6; j++)
        {
            if (!brickDataList.bricks[idx].IsActive)
            {
                poolManager.DisableObj(poolManager.pool[i, j]);
            }
            else
            {
                Brick brick = poolManager.pool[i, j].GetComponent<Brick>();
                if (brick != null)
                {
                    brick.SetHP(brickDataList.bricks[idx].HP);
                    brick.SetScore(brickDataList.bricks[idx].Score);
                }
            }
            idx += 1;
        }
    }
}

 

그 이후 LevelPoolSpawn 함수가 실행되면, brickDataList의 데이터를 검사해준다

 

만약 brickDataList.bricks[idx]의

IsActive가 false이면?

오브젝트 풀의 해당 벽돌을 SetActive(false) 해준다.

IsActive가 true이면?

오브젝트 풀의 Brick 컴포넌트를 가져와 brickDataList 데이터의 HP, Score을 적용해준다