728x90
- 주제
>> Object Pooling 개념 이해
>> ObjectPool 클래스
>> ItemManager 클래스
>> 아이템 드랍 예시
>> 장점
- 공부내용
게임 개발에서 객체를 매번 생성하고 삭제하는 대신, 미리 생성한 객체들을 재사용하는 Object Pooling 기법을 사용하면 성능을 크게 향상시킬 수 있다.
이 기법은 특히 아이템이나 파티클처럼 자주 생성되고 삭제되는 객체들에 유용하다. 이 예제에서는 아이템 풀링 시스템을 구축하여, 게임 내에서 아이템이 필요할 때마다 풀에서 가져와 사용하고, 사용이 끝나면 다시 풀로 반환하는 방식을 설명한다.
1. Object Pooling 개념 이해
게임에서 객체를 매번 생성하고 삭제하는 것은 성능에 부담을 줄 수 있다. Object Pooling은 미리 일정 수의 객체를 생성해 놓고, 필요할 때마다 재사용하는 방식으로, 메모리 할당과 해제를 줄여 성능을 최적화한다.
2. ObjectPool 클래스<T>
using System.Collections.Generic;
using UnityEngine;
public class ObjectPool<T> where T : Component
{
private readonly T prefab; // 풀에 들어갈 객체의 프리팹
private readonly Queue<T> objects = new Queue<T>(); // 객체 큐
private readonly Transform parent; // 객체들이 속할 부모 객체
// 초기화
public ObjectPool(T prefab, int initialCount, Transform parent = null)
{
this.prefab = prefab;
this.parent = parent;
// 초기 객체를 풀에 추가
for (int i = 0; i < initialCount; i++)
{
var obj = GameObject.Instantiate(prefab, parent);
obj.gameObject.SetActive(false); // 비활성화 상태로 초기화
objects.Enqueue(obj); // 큐에 추가
}
}
// 객체를 풀에서 가져오는 메서드
public T Get()
{
if (objects.Count > 0)
{
var obj = objects.Dequeue();
obj.gameObject.SetActive(true); // 객체를 활성화
return obj;
}
// 풀에 객체가 없으면 새로 생성
var newObj = GameObject.Instantiate(prefab, parent);
newObj.gameObject.SetActive(true);
return newObj;
}
// 객체를 풀에 반환하는 메서드
public void ReturnToPool(T obj)
{
obj.gameObject.SetActive(false); // 객체를 비활성화
objects.Enqueue(obj); // 큐에 반환
}
}
3. ItemManager 클래스
아이템을 관리하는 ItemManager 클래스를 작성하여, 게임 내에서 드랍되는 아이템들을 풀링한다. 예를 들어, 체력 회복 아이템과 마나 회복 아이템을 풀에서 가져와 게임 내에 드랍할 수 있다.
using System.Collections;
using UnityEngine;
public class ItemManager : MonoBehaviour
{
public Transform ParentItem; // 아이템이 위치할 부모 오브젝트
[Header("아이템 프리팹")]
public GameObject HealthPotionPrefab; // 체력 회복 아이템
public GameObject ManaPotionPrefab; // 마나 회복 아이템
private ObjectPool<GameObject> healthPotionPool; // 체력 회복 아이템 풀
private ObjectPool<GameObject> manaPotionPool; // 마나 회복 아이템 풀
private static ItemManager _instance;
public static ItemManager Instance => _instance ?? throw new System.InvalidOperationException("ItemManager 인스턴스가 존재하지 않습니다.");
#region 싱글톤(Awake)
private void Awake()
{
if (_instance == null) _instance = this;
}
#endregion
private void Start()
{
InitializePools();
}
// 풀 초기화
private void InitializePools()
{
healthPotionPool = new ObjectPool<GameObject>(HealthPotionPrefab, 5, ParentItem);
manaPotionPool = new ObjectPool<GameObject>(ManaPotionPrefab, 5, ParentItem);
}
// 아이템 드랍 (체력 회복 아이템)
public void DropHealthPotion(Vector3 position)
{
var potion = healthPotionPool.Get(); // 풀에서 아이템 가져오기
potion.transform.position = position; // 아이템 위치 설정
StartCoroutine(ReturnItemToPool(potion, 5f)); // 5초 후 풀로 반환
}
// 아이템 드랍 (마나 회복 아이템)
public void DropManaPotion(Vector3 position)
{
var potion = manaPotionPool.Get(); // 풀에서 아이템 가져오기
potion.transform.position = position; // 아이템 위치 설정
StartCoroutine(ReturnItemToPool(potion, 5f)); // 5초 후 풀로 반환
}
// 일정 시간 후 아이템을 풀로 반환하는 메서드
private IEnumerator ReturnItemToPool(GameObject item, float delay)
{
yield return new WaitForSeconds(delay); // 시간 대기
item.SetActive(false); // 아이템 비활성화
healthPotionPool.ReturnToPool(item); // 풀로 반환 (아이템 종류에 따라 다르게 처리 가능)
}
}
4. 아이템 드랍 예시
게임 내에서 아이템이 드랍될 때마다 ItemManager를 통해 풀에서 아이템을 가져와 사용한다. 예를 들어, 체력 회복 아이템과 마나 회복 아이템을 특정 위치에 드랍할 수 있다.
// 체력 회복 아이템 드랍
ItemManager.Instance.DropHealthPotion(new Vector3(10, 5, 0));
// 마나 회복 아이템 드랍
ItemManager.Instance.DropManaPotion(new Vector3(5, 3, 0));
5. 장점
- 성능 최적화: 객체를 매번 생성하고 삭제하는 대신, 풀에서 재사용하여 성능을 개선할 수 있다.
- 자원 낭비 최소화: 매번 새로 생성하는 것보다 미리 생성해두고 재사용함으로써 자원을 절약할 수 있다.
- 간결한 코드 관리: 아이템이나 파티클 객체가 많을 경우, 풀링을 통해 코드를 간결하고 효율적으로 관리할 수 있다.
728x90
반응형
'유니티' 카테고리의 다른 글
Day 44 - 구글 스프레드시트와 유니티 연동 및 다국어 데이터 관리 (2부) (2) | 2024.12.07 |
---|---|
Day 43 - 구글 스프레드시트와 유니티 연동 및 다국어 데이터 관리 (1부) (2) | 2024.12.06 |
Day 41 - WebGL로 웹 새로고침 시 게임 상태 저장하기 (0) | 2024.12.05 |
Day 40 - 상태머신(3D 방치형 게임 만들기 中) (0) | 2024.06.18 |
Day 39 - SoundManager(오브젝트 풀에서 사운드 소스를 가져와 재생) (0) | 2024.06.12 |