본문 바로가기

게임개발

[Unity] 픽셀 아트 플립북 애니메이션 구현 실험 2

지난 포스트에 이어서 이번엔 Unirx를 사용해보았다.

이 방식에서는 SpriteRenderer로 접근해 Sprite를 직접 교체하는 방식으로

기존 애니메이션 클립을 이용한 방법과 애니메이션을 그리는 방법에서는 일맥 상통한다.

Addressable을 사용했다.

  1. Shader Graph 사용
  2. Unirx 사용 - (기존 애니메이션 클립에서 스프라이트를 직접 바꾸는 방법과 유사하다.)

 

이 포스트에서는 rx의 timer를 사용하여 애니메이션을 그리며 테스트 환경은 Unity 2021 lts이다.

아래는 폴리톤이라는 몬스터로 지금 제작하고 있는 게임에 첫 등장하는 몬스터로 작업.

각 애니메이션은 초 당 8장이 넘어가도록 설정했다.

<사용 된 코드(더보기 버튼으로로 볼 수 있습니다)>

더보기
public class RxAnimTest : MonoBehaviour
{
    public GameObject prefab;
    public int TestSize=100000;
    public TMP_Text text;
    public static IList<Sprite> papers;
    public List<SpriteAnimation> obj;
    public int state=1;
    
    void Awake()
    {
        papers = Addressables.LoadAssetAsync<IList<Sprite>>("polyton").WaitForCompletion();
        Debug.Log(papers.Count);
    }
    
    public void OnGenerate()
    {
        Stopwatch sw = new();
        Random random = new(1234);
        sw.Start();
        for (int i = 0; i < 100000; i++)
            obj.Add(Instantiate<GameObject>(prefab, new Vector3(random.NextFloat(-4,4), random.NextFloat(-4,4), 0f),
                Quaternion.identity).GetComponent<SpriteAnimation>()); 
        sw.Stop();
        text.SetText($"result: {sw.ElapsedMilliseconds}ms");
    }
    
    public void OnTransition()
    {
        Stopwatch sw = new();
        sw.Start();
        foreach (var o in obj)
        {
            o.SetState(state);
        }
        sw.Stop();
        text.SetText($"result: {sw.ElapsedMilliseconds}ms");
    } 
}

 

public class SpriteAnimation : MonoBehaviour
{
    private SpriteRenderer _renderer;
    public int state = 0;
    void Awake()
    {
        _renderer = gameObject.GetComponent<SpriteRenderer>();
        Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1 / 8f))
            .Subscribe(
                i =>
                {
                    _renderer.sprite = RxAnimTest.papers[ state + (int) i % 8];
                }
        );
    }

    public void SetState(int i)
    {
        state = i * 8;
    }
}

 

 

 

  • 10만개를 생성한 모습. 상당히 오랜 시간이 걸린다. 부하도 상당한 것  같다.

 

 

  • 첫 번째 트랜지션을 한 이 후: 

 

 

  • 여러 번 트랜지션을 한 이후

 

확실히 트랜지션은 빠르다는 점에서

셰이더 그래프의 프로퍼티를 빈번하게 직접 세팅하는 것이 과연 맞는 접근인가 했을 때

자연스러운 것은 아니라는 점은 확실히 보이긴 한다.

위에서도 보이듯 트랜지션에서는 차이가 났기 때문이다.

 

셰이더 보다 전체적으로 메모리도 훨씬 매우 많이 먹는다. 그래서 움직일 때 프레임 저하도 훨씬 컸다.

그러나! 놀라운 것은 빌드 후 rx로 짠 코드가 훨씬 쾌적했다는 점이다.

아래는 빌드 후 테스트 영상이다. (윈도우 ILLCPP로 빌드한 결과이다)

메모리는 첫 생성시 800메가 정도 계속 트랜지션을 해도 메모리는 1기가를 넘어가지 않았다. 생성 비용은 크지만 부하가 훨씬 적은 것 같다.