2 minute read

작업 내용

발표

발표를 하면서 배운 점이 많았다. 일단 UI가 해상도에 따라 달라질 것을 준비해서 맞춰질 수 있게 해야하다.
그보다 중요한건 우리팀 작품에 대해 오브젝트 풀이 잘못 쓰였다는 것이다.
별 생각 없이 유닛 생산은 자주 일어나니까 무작정 썼는데, 피드백에서 오브젝트풀은 생성과 파괴가 자주 일어날 때만 쓰는 것이라는 소리를 듣고 유닛 생산에서 빼서 대신 자주 생산/파괴 되는 화살과 팝업 텍스트에 쓰기로 했다.
그러려다보니 일단 기존에 유닛 생산에서만 쓰던 방식을 수정해서 제너릭 오브젝트 풀로 바꾸었다.

오브젝트 풀 변화와 화살 생성 방식 변화

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[System.Serializable]
public class ObjectInPool
{
    public GameObject prefab;
    public int size;

    public GameObject GetNewObject()
    {
        return GameObject.Instantiate(prefab);
    }
}

[System.Serializable]
public class TagObjectPair<T>
{
    public T Tag;
    public ObjectInPool Object;
}

public class ObjectPool<T> where T : System.Enum
{
    

    private Dictionary<T, ObjectInPool> objectsInPool;
    private Dictionary<T, Queue<GameObject>> poolDictionary;

    public void InitializePool(TagObjectPair<T>[] tagobpair)
    {
        objectsInPool = new Dictionary<T, ObjectInPool>();
        poolDictionary = new Dictionary<T, Queue<GameObject>>();

        foreach(TagObjectPair<T> op in tagobpair)
        {
            this.objectsInPool[op.Tag] = op.Object;
        }

        foreach (var o in objectsInPool)
        {
            T key = o.Key;

            Queue<GameObject> poolObjects = new Queue<GameObject>();
            for (int i = 0; i < o.Value.size; i++)
            {
                GameObject obj = GameObject.Instantiate(o.Value.prefab);
                obj.SetActive(false);
                poolObjects.Enqueue(obj);
            }
            poolDictionary.Add(key, poolObjects);
        }
    }

    // 오브젝트 풀 불러오기
    public GameObject SpawnFromPool(T tag)
    {
        if (!poolDictionary.ContainsKey(tag))
        {
            Debug.LogWarning($"Tag {tag} does not exist in the pool.");
            return null;
        }

        GameObject obj = null;
        if (poolDictionary[tag].Count > 0)
        {
            obj = poolDictionary[tag].Dequeue();
        }
        else
        {
            obj = objectsInPool[tag].GetNewObject();
        }

        obj.SetActive(true);
        return obj;
    }

    public GameObject SpawnFromPool(T tag, Vector3 position)
    {
        GameObject obj = SpawnFromPool(tag);
        if (obj != null)
        {
            obj.transform.position = position;
        }
        return obj;
    }

    // 오브젝트풀 추가용
    public void AddObjectPool(T tag, GameObject prefab, int size)
    {
        if (!poolDictionary.ContainsKey(tag))
        {
            poolDictionary[tag] = new Queue<GameObject>();
        }

        for (int i = 0; i < size; i++)
        {
            GameObject obj = GameObject.Instantiate(prefab);
            obj.SetActive(false);
            poolDictionary[tag].Enqueue(obj);
        }
    }

    public void ReturnObject(T tag, GameObject obj)
    {
        if (!poolDictionary.ContainsKey(tag))
        {
            poolDictionary[tag] = new Queue<GameObject>();
        }

        obj.SetActive(false);
        poolDictionary[tag].Enqueue(obj);
    }
}

오브젝트 풀을 T로 정해진 enum으로 오브젝트들을 구별해서 한가지 주제의 오브젝트들을 담을 수 있게 만들고, 인스펙터창에서 넣어준 오브젝트들을 awake에서 풀에 넣어준다.
이제 UserData 스크립트에서

public ObjectPool<ProjectileNames> ObjectPool { get; private set; }

이라고 화살 하나 넣어주면 나머지는 이전에 화살을 생성해서 쏘던 코드를 수정하면 그만이다.

새로운 게임 기획 아이디어

그리고 다른팀들 발표를 보면서 우리가 pc게임으로 만들 생각이라면 좀 더 컨텐츠가 필요하다 생각해 새로운 디펜스 게임을 참고하기로했다.
참고한 게임은 킹덤 러쉬인데 거기서 배운 점은 다음과 같다 :
적이 한번에 여러마리 겹치도록 많이 등장(대신 완전히 겹치지는 않게 조금 콜라이더를 두거나 하기)

배속 시스템(디펜스 게임 자체가 늘어지기 좋아서 배속을 적용해서 빠르게 넘길 웨이브는 빨리 넘길 수 있게 해주기) (배속은 그래픽 깨지지 않을 속도까지만)

생산 건물을 따로 건설해야함

플레이어 스킬이 존재함 (우리는 대신 영웅이나 유닛 자체 스킬 적용)

영웅의 존재 (우리는 네모네모 디펜스처럼 기본 유닛 몇마리 조합하면 영웅이 되게 할 수도? 그리고 유닛 생산시 매우 낮은 확률로 영웅이 등장)

적 체력바 (맞는 애니메이션 대신 위에 체력바를 표시해줌)

한번에 여러 통로로 적들이 출연 (이를 막기 위해 패트롤 기능도 좋을듯)

이에 대해서는 나중에 팀원들과 상의해서 추가할듯 하다.

마무리

오늘은 캠프 팀들 발표를 보고 우리 팀도 발표 후 피드백을 받으며 지금까지 결과를 정리하는 시간이었다.
그래서 많은 변화는 없었지만 나름 배운점이 많은 것 같다.