Ch 3. 노트 오브젝트 풀링
카테고리: Unity Lesson 4
태그: Unity Game Engine
케이디님의 [유니티 강좌] 리듬 게임 유튜브 강의를 듣고 정리한 필기입니다. 😀
🌜 강의 들으러 가기 Click
🚀 오브젝트 풀링
- 객체 생성과 객체 파괴는 모바일 환경에서 매우 소모적인 일이라서 버벅일 수 있다.
 - 따라서 생성과 파괴를 최소화 하기 위해 미리 일정 갯수의 오브젝트들을 미리 생성해둔 다음 객체를 활성화해서 재활용해 쓰고 파괴 하는 대신 다시 비활성화 하는 식으로 관리하는 것을 오브젝트 풀링이라고 한다.
 
🚀 노트를 오브젝트 풀링으로 관리
- 미리 노트를 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; // 공유자원

- 프리팹은 오브젝트들을 
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);
        }
    }
노트가 생성되야할 때는 실제로 생성하진 않고 큐에서 하나씩 꺼내와서 활성화만 시키면 되고 노트가 파괴되야 할 때는 실제로 파괴하진 않고 비활성화해서 다시 큐에 넣어주면 된다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우 
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
      
    
댓글 남기기