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