Ch 3. 노트 오브젝트 풀링

Date:     Updated:

카테고리:

태그:

케이디님의 [유니티 강좌] 리듬 게임 유튜브 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click

🚀 오브젝트 풀링

  • 객체 생성과 객체 파괴는 모바일 환경에서 매우 소모적인 일이라서 버벅일 수 있다.
  • 따라서 생성과 파괴를 최소화 하기 위해 미리 일정 갯수의 오브젝트들을 미리 생성해둔 다음 객체를 활성화해서 재활용해 쓰고 파괴 하는 대신 다시 비활성화 하는 식으로 관리하는 것을 오브젝트 풀링이라고 한다.


🚀 노트를 오브젝트 풀링으로 관리

image

  • 미리 노트를 15 개 생성해놓고 비활, 활성화 해가며 쓴다.
    • 오브젝트 풀을 큐에서 관리할 것이다.
      • 노트 객체 15개 中 마치 생성된 것처럼 활성화 된 것은 큐에서 빠져나오고 마치 파괴된 것처럼 비활성화 한 것은 다시 큐에 삽입해 큐에서 보관할 것이다.
      • 큐는 선입 선출이므로 큐에 있은지 가장 오래된 것을 우선적으로 활성화한다.

📜ObjectPool

빈 오브젝트 ObjectPool에 붙임

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

[System.Serializable]
public class ObjectInfo
{
    public GameObject goPrefab;
    public int count;
    public Transform tfPoolParent;
}

public class ObjectPool : MonoBehaviour
{
    [SerializeField] ObjectInfo[] objectInfo = null;

    public Queue<GameObject> noteQueue = new Queue<GameObject>(); // Pool

    public static ObjectPool instance; // 공유자원

image

  • 프리팹은 오브젝트들을 count갯수만큼 생성하며 이를 오브젝트 풀링으로 관리할 것이다.
    • 비활성화인 상태의 오브젝트들은 큐 안에 보관
  • 관리할 오브젝트의 정보는 OjbectInfo에 담겨 있다.
    • 이 오브젝트를 찍어낼 프리팹 goPrefab
    • 오브젝트 몇 개를 사용할 것인지 count
    • 누구의 자식으로 될 것인지 tfPoolParent
  • 일단 오브젝트 풀링으로 관리할 것은 현 시점에선 노트뿐이라 objectInfo 배열은 원소 1 개 뿐이다. 노트만!
    • 노트인 objectInfo[0]을 15개 (노트의 count) 를 미리 생성해둔 후 관리될 것.
  • noteQueue
    • 활성화되서 화면 안에 들어가는 노트는 큐에서 빠진다.
    • 비활성화 되서 다시 활성화 되기를 기다리는 노트는 큐에 들어간다.
      • 큐에 들어간지 가장 오래된 노트가 먼저 활성화 됨.
  • instance
    • 이 📜OjbectPool 이 붙은 오브젝트가 공유되고 하나로 유지될 수 있도록.
    void Start()
    {
        instance = this;
        noteQueue = InsertQueue(objectInfo[0]);
    }

    Queue<GameObject> InsertQueue(ObjectInfo p_objectInfo)
    {
        Queue<GameObject> temp_Queue = new Queue<GameObject>();
        for (int i = 0; i < p_objectInfo.count; i++)
        {
            GameObject temp_clone = Instantiate(p_objectInfo.goPrefab, transform.position, Quaternion.identity);
            temp_clone.SetActive(false);
            if (p_objectInfo.tfPoolParent != null)
                temp_clone.transform.SetParent(p_objectInfo.tfPoolParent);
            else
                temp_clone.transform.SetParent(this.transform);

            temp_Queue.Enqueue(temp_clone);
        }

        return temp_Queue;
    }
}

게임이 시작되면 objectInfo[0] 즉 노트가 count개 즉 15개 생성되고 모두 비활성화 한 상태로 큐에 넣는다.


📜Note

    void OnEnable()
    {
        if(noteImage == null)
            noteImage = GetComponent<Image>();

        noteImage.enabled = true;
    }

오브젝트 풀링으로 관리 될 것이라서 미리 만들어진 노트들이 계속 재활용 된다. 따라서 이미지 또한 다시 켜주면 된다.


📜NoteManager

    void Update()
    {
        currentTime += Time.deltaTime;

        if (currentTime >= 60d / bpm) // 60/bpm = 한 비트당 시간 (120bpm이라면 한 비트당 소요 시간은 0.5초)
        {
            GameObject t_note = ObjectPool.instance.noteQueue.Dequeue();
            t_note.transform.position = tfNoteAppear.position;
            t_note.transform.localScale = new Vector3(1f, 1f, 0f);
            t_note.SetActive(true);

            theTimingManager.boxNoteList.Add(t_note);
            currentTime -= 60d / bpm;  
        }            
    }

    private void OnTriggerExit2D(Collider2D collision)
    {
        if (collision.CompareTag("Note"))
        {
            if (collision.GetComponent<Note>().GetNoteFlag())
                theEffect.JudgementEffect(4);
            theTimingManager.boxNoteList.Remove(collision.gameObject);
            
            ObjectPool.instance.noteQueue.Enqueue(collision.gameObject);
            collision.gameObject.SetActive(false);
        }
    }

노트가 생성되야할 때는 실제로 생성하진 않고 큐에서 하나씩 꺼내와서 활성화만 시키면 되고 노트가 파괴되야 할 때는 실제로 파괴하진 않고 비활성화해서 다시 큐에 넣어주면 된다.



🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄

맨 위로 이동하기

Unity Lesson 4 카테고리 내 다른 글 보러가기

댓글 남기기