카테고리 보관물: 개발

유니티(Unity) Animator Override Controller 이용해서 애니메이션 변경하기

개요

게임을 개발하다 보면 기본적인 동작은 동일한데 외형만 변경되는 경우가 있습니다. 각각 Animator Controller를 생성해서 관리할 수도 있지만 종류가 많아지면 관리하기 너무 힘들게 됩니다. 이럴 때 Animator Override Controller 를 사용해서 하나의 Animator Controller 만 적용하도록 할 수 있습니다.

Animator Override Controller

Animator Override Controller 의 설명은 다음 주소에서 확인하실 수 있습니다. 핵심은 Animator Controller를 하나만 사용할 수 있다는 것 입니다.

https://docs.unity3d.com/kr/2020.3/Manual/AnimatorOverrideController.html

대략적인 설명과 예시를 보여주고 있는데 필자의 입장에서는 딱 와 닿지 않았습니다. 실제 예를 살펴보면서 알아보도록 하겠습니다.

게임 내 적 우주선 예시

적 우주선은 플레이어의 탄환을 맞으면 폭발하는 공통적인 특징을 가지고 있습니다. 적 우주선의 Animator Controller의 상태를 를 간단히 작업하면 예시와 같은 모양이 됩니다.

적 우주선 Animator Controller
적 우주선 Animator Controller

Assets/Resources 에 Animator Override Controller(마우스 우측버튼 > Create > Animator Override Controller) 를 생성합니다. 생성 후 위에서 정의한 Animator Controller를 지정합니다(예시에서는 enemy 라는 이름으로 작업).

Animator Override Controller에 Animator Controller를 지정한 상태
Animator Override Controller에 Animator Controller를 지정한 상태

여기에서 주의할 사항은 Animator Controller의 각 상태에 Motion 이 지정되어 있어야 Explosion, Fly, Hit 같은 항목이 나타난다는 것 입니다. 이런 이름들은 Motion에 지정된 Animation Clip 을 따릅니다. 필자는 처음에 Motion을 지정하지 않아도 상태 이름으로 나타날 것으로 예상했는데 그렇지 않아서 다른 문제가 있는지 알았습니다.

Animator Controller 의 Fly 상태 Motion 지정

Prefab을 하나 만들고 위의 Animator Controller 를 적용합니다. 작업을 완료하면 다음과 같이 됩니다. 이렇게 하면 각각의 Animator Override Controller 에 지정한 Animation Clip 이 적용되어 하나의 Animator Controller를 쓰면서 외형이 다른 애니메이션을 구현할 수 있습니다.

Animator Controller 에 Enemy01 Animator Override Controller 를 지정한 상태
Animator Controller 에 Enemy01 Animator Override Controller 를 지정한 상태

실행 중 상태에서 Animator Override Controller 변경하기

적 우주선의 종류가 게임이 실행되는 도중 조건에 따라 결정되는 경우가 있을 수 있습니다. 하나의 Prefab을 이용하고 Animator Controller 를 변경해서 외형을 변경하는 방법입니다. 다음의 코드와 같이 적용하면 됩니다.

var resourceName = "Animator Override Controller/Enemy0" + enemyType.ToString();
var animator = enemy.gameObject.GetComponent<Animator>();
animator.runtimeAnimatorController = (RuntimeAnimatorController)Resources.Load(resourceName);

유니티 에디터에서 Assets/Resources/Animator Override Controller 경로에 Enemy01, Enemy02 와 같은 이름으로 Animator Override Controller를 생성했습니다. 조건에 의해 enemyType이 정해지면 그것에 맞게 Animator Override Controller 가 적용되도록 했습니다.

이번글에서는 동작이 같고 외형만 변경되는 애니메이션을 쉽게 변경/관리할 수 있는 Animator Override Controller에 대해서 알아보았습니다.

유니티 OnBecameInvisible 이벤트 발생하지 않는 문제 조치법

개요

유니티에서 OnBecameInvisible 이벤트를 이용해서 게임 오브젝트가 화면에서 보이지 않게 되었을 때의 동작을 지정할 수 있습니다. 그런데 이벤트가 발생하지 않아 혼동을 주는 경우가 있습니다. 이 사례를 알아보고 해결방법도 같이 알아보도록 하겠습니다.

호출되지 않는 경우

OnBecameInvisible 이벤트는 게임 오브젝트가 화면에 보여지지 않으면 발생하게 됩니다. 그런데 작업 도중 플레이해 보면 화면상에서 사라졌는데 호출되지 않는 경우가 있습니다.

처음에 필자는 에뮬레이터에서 보여지는 것과 Scene 에서 보여지는 것이 다르다는 것을 생각하지 못했습니다. 에뮬레이터 기준으로는 화면에서 사라졌는데 Scene 상에서는 사라지지 않은 것으로 판단되어 호출되지 않았습니다.

해결방법

이럴 때 Scene 탭을 닫거나 Scene 의 화면 확대/축소 비율을 확인해서 조정하면 됩니다.

Scene 탭
Scene 탭

Scene 탭을 닫으면 이벤트가 정상적으로 호출됩니다. 정확하게 화면에서 사라지는 기준을 어떻게 판단하는지는 알 수 없었습니다. 하지만 OnBecameInvisible는 정상적으로 호출되었습니다. 그러나 Scene 탭을 닫으면 동작하는 모습을 확인할 수 없어서 불편합니다. Scene에 UI 항목이 추가되어 있고 Scene이 아주 작게 축소되어 버튼, 텍스트등이 보이게 되면 OnBecameInvisible 이벤트가 발생하려면 아주 오랜시간 기다려야 합니다.

아래 이미지를 보면 아래쪽 부분이 실제 화면상에 보이는 크기입니다. 강조한 부분이 게임 오브젝트입니다. 화면 밖으로 나가더라도 카메라가 아주 먼 곳에 위치한 것 처럼되어 Scene 창에서 보이지 않게되어야 이벤트가 발생합니다.

실제 Scene 크기와 UI 비율 차이
실제 Scene 크기와 UI 비율 차이

그래서 아래의 이미지 처럼 실제 게임 오브젝트가 보이는 비율로 확대하면 정상적으로 OnBecameInvisible 이벤트가 호출되도록 할 수 있습니다.

Scene 영역 확대
Scene 영역 확대

이번글에서는 OnBecameInvisible 이벤트가 발생하지 않는 현상과 해결방법에 대하여 알아보았습니다.