오브젝트 풀링
여러가지 게임 중에 같은 오브젝트들이 반복해서 나오는 상황이 발생하는 게임이 있다.
예를 들어 아래 사진처럼 뱀서라이크 게임에서 같은 몬스터가 반복적으로 나올때라던지
오브젝트 풀링을 모른다면 위 상황을 연출할때 박쥐를 생성할땐 Instantiate를 사용하고 삭제할 때는 Destroy를 사용할 것이다. 하지만 Instantiate와 Destroy를 사용하면 안좋다는것은 조금만 구글링해도 금방 알 수 있듯이 이를 해결하기 위해 보통 오브젝트 풀링을 사용한다.
오브젝트 풀링이란 게임에서 자주 사용되는 객체를 미리 생성하여 필요할 때 활성화/비활성화를 통해 재활용하여 성능을 최적화하는 기법이다.
원리는 다음과 같다.
1. 풀링 생성: 게임이 시작될 때 미리 정해진 개수의 오브젝트를 생성하여 풀(오브젝트들을 관리할 공간)에 저장한다.
2. 오브젝트 재사용: 게임 실행 중에 오브젝트가 필요할 때마다 풀에서 사용 가능한 오브젝트를 꺼내서 재사용한다. 이때 생성과 소멸의 비용이 들지 않는다.
3. 재활용 및 관리: 오브젝트를 사용한 후에는 풀에 다시 넣어 재활용할 수 있도록 한다. 풀이 가득 차면 새로운 오브젝트를 동적으로 생성하여 풀에 추가할 수도 있다.
이러한 방식으로 오브젝트 풀링은 불필요한 객체 생성 및 소멸을 피하고, 게임의 성능을 최적화할 수 있다. 특히 모바일 기기나 리소스 제한이 있는 환경에서 유용하게 활용된다.
오브젝트 풀링을 직접 구현하는 방법도 있지만 여기선 유니티에서 지원하는 오브젝트 풀링을 사용할 것이다. 고로 네임스페이스에 using UnityEngine.Pool 를 추가하는 것을 잊지말자.
주요 스크립트
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
public class Spawner : MonoBehaviour
{
[SerializeField] Transform Player;
[SerializeField] GameObject prefabs_Monster;
[SerializeField] int spawn_Count;
[SerializeField] int spawn_radius;
[SerializeField] int maxPoolsize;
private IObjectPool<Monster> _Pool;
void Start()
{
_Pool = new ObjectPool<Monster>(CreateMonster, OnGetMonster, OnReleaseMonster, OnDestroyMonster, true, 10, maxPoolsize);
StartCoroutine(spawn());
}
IEnumerator spawn()
{
WaitForSeconds waitflag = new WaitForSeconds(0.1f);
for (int i = 0; i < spawn_Count; i++)
{
var monster = _Pool.Get();
Vector2 pos_randOnSpherePos = Random.onUnitSphere * spawn_radius;
monster.transform.position = new Vector3(pos_randOnSpherePos.x, 0, pos_randOnSpherePos.y);
monster.transform.LookAt(Player.position);
yield return waitflag;
}
}
private Monster CreateMonster()
{
Monster monster = Instantiate(prefabs_Monster).GetComponent<Monster>();
monster.SetManagedPool(_Pool);
return monster;
}
private void OnGetMonster(Monster monster)
{
monster.gameObject.SetActive(true);
}
private void OnReleaseMonster(Monster monster)
{
monster.gameObject.SetActive(false);
}
private void OnDestroyMonster(Monster monster)
{
Destroy(monster.gameObject);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Pool;
public class Monster : MonoBehaviour
{
private IObjectPool<Monster> Monsterpool;
void Update()
{
transform.Translate(Vector3.forward * 5 * Time.deltaTime);
}
private void OnTriggerEnter(Collider other)
{
if (other.CompareTag("Player"))
{
DestroyMonster();
}
}
public void SetManagedPool(IObjectPool<Monster> pool)
{
this.Monsterpool = pool;
}
public void DestroyMonster()
{
this.Monsterpool.Release(this);
}
}
결과
'Unity > 정보' 카테고리의 다른 글
[Unity] 2D 랜덤 맵 생성(Celluar Automata) (0) | 2024.01.20 |
---|---|
[Unity] New Input System (1) | 2024.01.13 |
[Unity] 모바일 게임 성능 최적화 (0) | 2024.01.02 |
[Unity] 사운드 매니저 (0) | 2023.12.03 |
[Unity] AOS Fog of War 에셋 (0) | 2023.12.02 |