유니티(Unity) IObjectPool 을 사용한 오브젝트 풀링(Object Pooling)

개요

게임내에서 많은 오브젝트를 생성하고 파괴하는 과정은 많은 비용을 소모합니다. 비용을 최소화하기 위해 오브젝트 풀링(Object Pooling)을 사용합니다. 미리 오브젝트를 만들어 놓고 필요할 때마다 꺼내서 사용하는 개념으로 생각하면 됩니다.

오브젝트 풀링을 직접 구현할 수도 있고 애셋스토어에 있는 것을 사용해도 됩니다. 그러나 유니티에서 자체적으로 지원합니다. 2021 버전부터 지원합니다.

사용

가장 먼저 생각해 볼 수 있는 것이 플레이어나 적의 탄환입니다. 기본적으로는 탄환 오브젝트를 생성되고 파괴되는 방식으로 구현할 수 있습니다. 이렇게 하지 않고 IObjectPool 을 이용한 방법으로 구현해 보겠습니다.

게임 오브젝트(플레이어 탄환)를 하나 만들고 다음 스크립트를 생성한 후 연결해 줍니다.

public class PlayerBullet : MonoBehaviour
{
    private IObjectPool<PlayerBullet> playerBulletPool;

    public void SetPool(IObjectPool<PlayerBullet> objectPool)
    {
        playerBulletPool = objectPool;
    }

    private void OnBecameInvisible()
    {
        playerBulletPool?.Release(this);
    }
}

플레이어 게임 오브젝트와 연결된 스크립트에서 탄환을 발사하는 코드가 있다고 가정하고 다음과 같이 구현합니다.

public PlayerBullet playerBulletPrefabForPool; //PlayerBullet 클래스가 연결된 게임오브젝트
private IObjectPool<PlayerBullet> playerBulletPool;

private void Awake()
{
    playerBulletPool = new ObjectPool<PlayerBullet>(CreateBullet, OnGetBullet, OnReleaseBullet, OnDestroyBullet, maxSize: 10);
}

private PlayerBullet CreateBullet()
{
    PlayerBullet playerBullet = Instantiate(playerBulletPrefabForPool, playerTransform.position, Quaternion.identity);
    playerBullet.SetPool(playerBulletPool);
    return playerBullet;
}

private void OnGetBullet(PlayerBullet playerBullet)
{
    playerBullet.gameObject.SetActive(true);
    playerBullet.transform.position = playerTransform.position;
}

private void OnReleaseBullet(PlayerBullet playerBullet)
{
    playerBullet.gameObject.SetActive(false);
}

private void OnDestroyBullet(PlayerBullet playerBullet)
{
    Destroy(playerBullet.gameObject);
} 

1행은 PlayerBullet 클래스와 연결된 게임 오브젝트를 정의합니다. 이것을 유니티 에디터에서 연결해 줍니다.

6행은 실제 오브젝트 풀을 생성하고 필요한 메소드들을 정의합니다. 최대 숫자는 10으로 설정했습니다. 화면에 최대로 나타날 수 있는 개수를 고려하여 적절하게 조정합니다. 나머지 부분은 지정한 메소드의 이름으로 각각을 정의합니다.

탄환을 발사하는 부분에서는 다음과 같이 구현합니다. 탄환 게임 오브젝트를 Instantiate 로 생성하지 않고 오브젝트 풀에서 가져오도록 한 것이 가장 큰 차이점 입니다.

var playerBullet = playerBulletPool?.Get(); //오브젝트 풀에서 가져옴
//add your code
//GameObject bullet = Instantiate(playerBullet... //바로 생성

유니티 에디터에서 실행해서 보면 다음과 같이 활성화된 탄환(bullet-circle)과 비활성화된 탄환을 구별할 수 있습니다.

활성/비활성 플레이어 탄환

이렇게 오브젝트 풀링을 사용하면 탄환을 계속 생성/파괴하지 않고 효율적으로 구현할 수 있습니다. 메모리를 더 사용하게 되지만 생성/파괴되는 비용을 크게 낮출 수 있습니다.

파워토이(PowerToys)를 이용한 이미지 글자 추출

개요

여러가지 이유로 이미지에 있는 글자를 텍스트로 변환해야 하는 경우가 있습니다. 내용이 짧으면 보고 입력하면 되지만 양이 많으면 매우 지루한 작업이 됩니다. 이미지의 글자를 인식해서 글자로 변환해 주는 프로그램(OCR)이 많은데 파워토이에서 제공하는 기능만으로도 충분히 변환할 수 있습니다.

파워토이(PowerToys)

파워토이는 마이크로소프트사에서 배포하는 무료 유틸리티 세트입니다. 여러가지 기능을 제공하는데 텍스트 추출기를 이용해서 이미지 내의 글자를 가져올 수 있습니다. 여러가지 쓸모있는 기능이 많으니 설치하는 것을 추천드립니다. 필자는 주로 FancyZones, Color Picker, 텍스트 추출기를 주로 사용합니다.

파워토이 텍스트 추출기
파워토이 텍스트 추출기

텍스트 추출

파워토이를 설치하고 Win+Shift+T(기본값) 를 누르면 텍스트 추출기가 활성화 됩니다. 활성화되면 화면이 약간 어둡게 바뀝니다. 그리고 커서가 십자 모양으로 변경됩니다. 이 상태에서 텍스트로 변환하고자 하는 영역을 드래그 합니다.

텍스트 추출 영역 지정
텍스트 추출 영역 지정

위 이미지에서 텍스트 추출한 결과는 다음과 같습니다.

텍스트 추출 결과

결과를 보면 완전하지는 않은데 조금만 수정하면 되므로 전체를 타이핑 하는 것 보다는 시간이 많이 절약됩니다. 경험적으로 이미지가 클수록 폰트가 굵은 경우 정확하게 잘 텍스트가 추출되는 것 같았습니다.