Physics 

레이어로 Collider의 충돌 범위를 설정해서 특정한 충돌만 받아들이거나 무시하기

 

작성 기준 버전 :: 2019.2

 

[이 포스트의 내용은 유튜브 영상으로도 시청하실 수 있습니다]

 

이번 포스트에서는 유니티의 레이어로 Collider의 충돌 범위를 설정하는 방법을 알아보도록 하자.

 

두 개의 Collider가 충돌하면 OnCollision 혹은 OnTrigger 이벤트가 발생하며 개발자는 이 이벤트를 통해서 충돌을 감지했을 때 처리되어야 할 기능을 구현한다는 것을 기억할 것이다.

 

과연 게임에서는 어떤 상황과 이유에서 Collider의 충돌 범위를 설정해서 특정한 충돌을 받아들이거나 무시해야 할까?

 

만약 두 캐릭터가 서로를 향해서 총알을 발사한다고 생각해보자. 그런데 서로에게 발사한 총알끼리의 충돌을 무시하지 않고 그대로 두면 어떻게 될까? 총알끼리 충돌하면 서로에게 발사된 총알이 없어져 버리거나 튕겨져 나갈 것이다.

 

와! 총알을 쏴서 상대방의 총알을 막을 수 있는 게임이라니! 잘 만들면 꽤나 재밌고 멋있을 것 같은 컨셉이다.

 

하지만 대부분의 게임에서는 총알끼리의 충돌같은 건 구현하지 않고 무시하게 만들어버린다.

 

그 이유는 여러 가지가 있을 수 있는데 수많은 총알이 발생시키는 충돌로 게임의 성능이 저하될 수 있다는 것과 이런 총알로 총알을 맞출 수 있는 컨트롤 중심적인 시스템에서는 팬티만 입고 권총을 든 무시무시하고 고일 대로 고여버린 고인물이 달려와서 초보자가 쏜 총알을 모조리 막아버리고 초보자의 뚝배기를 터뜨려 버릴 수 있다는 것이다.

 

총알과 총알이 부딪히는 것 외에도 많은 문제가 있다.

 

어떠한 예외가 있을 수 있는지 살펴보자면 열심히 체력을 깎아놓은 몬스터가 힐팩에 스쳐서 건강해진다던가 플레이어는 던전 입구에서 헤매고 있는데 다른 층으로 넘어가는 콜라이더 앞에서 서성거리던 몬스터가 그 트리거를 건드려서 플레이어가 다음 층으로 넘아가던가 하는 많은 문제가 발생할 수 있다.

 

이걸 코드 레벨에서 막으려면 총알 클래스에는 충돌 검사를 할 때 충돌한 대상이 같은 총알이면 무시하는 코드를, 힐팩 클래스과 던전 층 이동용 트리거 클래스에서는 트리거에 닿은게 플레이어가 아니면 무시하는 코드를 작성해야 할 것이다. 이렇게 수동으로 일일이 예외를 막아야하는 경우가 많으면 많을수록 앞에서 언급한 것과 같은 어처구니가 없게 느껴지는 버그가 발생할 확률이 상승한다.

 

만약 이걸 별도의 코드 작업 없이 간단하고 일괄적으로 막을 수 있다면 당연히 그 방법을 써야될 것이다.

 

그게 바로 이번에 배울 유니티 레이어를 이용한 Collider 충돌 무시하기이다.

 

본격적인 내용에 들어가기에 앞서 아래에 있는 unity-mouse-input-practice.zip 파일을 다운로드 받아서 패키지를 임포트하도록 한다.

 

unity-mouse-input-practice.zip
다운로드

 

그리고 패키지에 포함되어 있는 Simple Character Test 씬을 열도록 한다.

 

 

먼저 게임를 플레이시키고 게임 뷰에 클릭해보면 클릭을 한 번 할 때마다 총알이 한 발씩 나가는 것을 볼 수 있다.

 

void Fire()
{
    //if(Input.GetMouseButtonDown(0))
    if(Input.GetMouseButton(0))
    {
        Vector3 firePos = transform.position + animator.transform.forward + new Vector3(0f, 0.5f, 0f);
        var bullet = Instantiate(bulletPrefab, firePos, Quaternion.identity).GetComponent<Bullet>();
        bullet.Fire(animator.transform.forward);
    }
}

 

SimpleCharacterController 스크립트를 열어서 Fire 함수 안에 있는 GetMouseButtonDown 함수를 GetMouseButton으로 바꾼 뒤, 코드를 저장하고 에디터로 돌아간다.

 

 

다시 게임을 플레이시키고 게임 뷰에서 마우스 왼쪽 버튼을 꾹 누르고 있으면 총알이 쏟아져 나오는 것을 볼 수 있다.

 

private void OnTriggerEnter(Collider other)
{
    if(other.GetComponent<Bullet>() == null)
    {
        Destroy(gameObject);
    }
}

 

그 다음에는 Bullet을 찾아서 스크립트 에디터를 열어보면 아래 쪽에 있는 트리거 감지 이벤트인 OnTriggerEnter에 앞에서 말한 것처럼 충돌 감지 예외를 코드 레벨에서 수동으로 처리하고 있는 것이 보일 것이다. 같은 총알끼리 부딪혔을 때는 무시하도록 작성되어 있다.

 

private void OnTriggerEnter(Collider other)
{
    //if(other.GetComponent<Bullet>() == null)
    {
        Destroy(gameObject);
    }
}

 

이 부분을 주석 처리 해버리면 어떻게 될까? 한 번 테스트 해보자.

 

 

게임을 플레이시키고 마우스를 클릭해보면 발사된 총알끼리 부딪혀서 앞으로 나가지 못하고 바로 사라져버리는 걸 볼 수 있다.

 

그럼 이걸 어떻게 코드 레벨의 예외처리 없이 원래대로 동작하게 만들 수 있을까?

 

이제부터 그걸 알아보자.

 

  

프로젝트 뷰에서 Prefabs 폴더 안에 있는 Bullet 프리팹을 더블클릭해서 프리팹 수정 씬을 열어보자. 그럼 선택된 Bullet 프리팹 게임 오브젝트의 내용을 인스펙터 뷰에서 볼 수 있는데 게임 오브젝트의 이름 아래를 보면 태그와 함께 Default라고 표시된 레이어를 찾을 수 있다.

 

레이어를 클릭해보면 Default, TrasparentFX, Ignor Raycast, Water, UI가 있다.

 

이 레이어에는 여러가지 역할이 있지만 대표적인 것이 바로 지금 배우고 있는 충돌 무시 설정이다.

 

항목들 중에서 제일 아래에 있는 [Add Layer]를 선택하면 레이어를 직접 만들 수 있다.

 

 

Bullet이라는 레이어를 만들어보자.

 

 

그리고 다시 Bullet 프리팹으로 돌아가서 레이어를 Bullet으로 설정한다.

 

그 다음은 레이어의 충돌 설정을 할 차례이다.

 

 

상단 메뉴 바에서 [Edit > Project Settings]를 선택해서 프로젝트 세팅 뷰를 연다.

 

 

이중에 Physics 탭으로 들어가면 레이어끼리의 충돌 설정을 할 수 있다. 가장 아래 쪽을 보면 직각삼각형 형태로 배치된 체크박스들을 볼 수 있는데 행이나 열마다 레이어의 이름이 적혀있는 것을 알 수 있다.

 

제일 앞 칸을 기준으로 보면 Default와 Bullet 사이는 체크가 되어있는데 이것은 Bullet 레이어와 Default 레이어의 오브젝트가 충돌하면 이 충돌을 감지하겠다는 뜻이다. 반대로 체크가 해제되면 두 레이어 사이의 충돌을 무시하겠다는 뜻이 된다.

 

우리는 Bullet끼리의 충돌을 무시할 계획이기 때문에 Bullet과 Bullet이 만나는 지점의 체크를 해제해준다.

 

프로젝트 세팅 뷰를 닫고 플레이를 시킨 뒤 총알을 발사해보자.

 

 

그럼 총알끼리 충돌해서 사라지지 않고 아주 잘 발사되는 것을 볼 수 있다.

 

단 레이어를 사용할 때 주의할 점은 사용자가 만들 수 있는 최대 레이어 갯수는 총 24개 뿐이기 때문에 불필요한 레이어를 함부로 남발하면 나중에 정작 필요한 레이어의 자리가 부족해지는 문제가 발생할 수 있다는 것이다.

 

반응형
  1. 료용 2020.04.22 01:51 신고

    베르님 유투브 파셨네요 좋은영상 기대하겠습니다.

    • wergia 2020.04.22 17:02 신고

      글만으로는 모자란 감이 있어서 구현 과정을 보여드리려고 만들었어요ㅎㅎ

Tutorial (7)

 

애니메이션

 

작성 기준 버전 :: 2018.3.2f1

 

[튜토리얼의 내용을 유튜브 영상을 통해서도 확인하실 수 있습니다.]

 

게임에서 캐릭터가 어떠한 동작도 하지 않고 가만히 멈춘 채로 플레이어가 입력하는 대로 움직이가만 한다면 그 게임은 과연 어떤 느낌일까? 아마 그것은 굉장히 기괴한 모습이거나, 게임이 완성되지 못한 느낌일 것이다. 이렇듯이 애니메이션은 게임에 생동감을 불어넣는 중요한 요소이다.

 

메카님(Mecanim)

 

유니티에서 지원하는 애니메이션 시스템을 유니티 측에서는 메카님이라고 이름을 붙였다. 이 메카님 시스템은 기본적인 애니메이션 기능은 물론 애니메이션 레이어, 애니메이션 블렌드, 애니메이션 리타게팅 등의 다양한 기능을 제공한다. 애니메이션과 관련된 고급 기능들은 이후에 다른 섹션을 통해서 알아보도록 하고 이번 섹션에는 메카님 시스템의 기초적인 애니메이션 기능을 알아보도록 하자.

 

 

애니메이션 클립과 애니메이터 컨트롤러(Animation Clip & Animator Controller)

 

유니티의 애니메이션 시스템은 해당 오브젝트가 어떻게 움직여야 하는지에 대한 정보들이 포함된 애니메이션 클립과 플로우 차트와 같은 방식으로 애니메이션 클립들을 구조화하여 현재 어떤 클립이 재생되어야 하고 언제 애니메이션이 변경되어야 하는지 등을 추적하는 상태머신 형태의 애니메이터 컨트롤러로 이루어진다.

 

애니메이터 컨트롤러와 애니메이션 클립의 아이콘 형태는 다음과 같다.

 

 

애니메이션 클립을 만드는 방법은 크게 두 가지가 있다. 첫 번째는 3ds Max나 Maya 같은 외부의 프로그램으로 애니메이션을 만들어서 임포트 하는 것이고, 다른 하나는 유니티에서 직접 애니메이션 키를 잡아서 클립을 만드는 것이다.

 

3ds Max 같은 외부 프로그램에서 애니메이션을 만들어서 임포트하는 방식은 3D 모델링의 애니메이션을 만들고자 할 때 주로 사용하며 유니티 엔진에서 직접 키를 잡아서 애니메이션 클립을 만드는 것은 비교적 간단한 애니메이션이나 UI 애니메이션을 만들고자 할 때 사용하는 빈도가 높다.

 

 

외부에서 만든 애니메이션 임포트하기

 

Practice Animation.zip
다운로드

 

우선은 외부에서 만들어진 애니메이션을 임포트하는 방법을 배워보자. 연습용 애니메이션은 위의 첨부파일을 다운로드 받으면 된다. 다운 받은 압축파일의 압축을 해제하면 BoxMan@Run.FBX, BoxMan@Stand.FBX, BoxMan@Walk.FBX, BoxMan@Attack.FBX 네 개의 FBX 파일이 나올 것이다. 일반적으로 외부의 3D 모델링 프로그램을 통해 만들어진 애니메이션들은 FBX 확장자를 가진 것을 사용한다.

 

 

이렇게 받은 네 개의 파일을 유니티 엔진의 프로젝트 뷰로 드래그&드롭 한다. 그렇게 하면 네 개의 파일이 우리의 프로젝트에 포함되는 것을 확인할 수 있다.

 

 

임포트된 FBX 파일은 프로젝트 뷰에서 파란 직육면체에 종이가 붙은 아이콘으로 표현되며, 그 앞의 작은 삼각형을 클릭해서 접힌 부분을 열면 그 아래에 애니메이션 클립이 포함되어 있는 것을 확인할 수 있다.

 

 

이 FBX 파일을 선택한 상태로 인스펙터 창에서 애니메이션의 이름이나 길이, 반복 여부 등을 수정할 수 있다.

 

 

 

 

 

유니티 엔진에서 직접 애니메이션 클립 만들기

 

 

유니티 엔진에서 직접 애니메이션 클립을 만드는 방법을 배우기 위해서는 우선 씬에 애니메이션 클립을 만들 게임오브젝트 하나를 생성한다.

 

 

그리고 생성된 오브젝트를 선택한다. 

 

 

그 다음에 상단 메뉴바에서 Window>Animation>Animation을 선택하거나 Ctrl+6 단축키를 누르면 애니메이션을 수정할 수 있는 애니메이션 패널이 열린다.

 

 

아직 큐브에는 다른 애니메이션이 없기 때문에 애니메이션 클립을 생성하게 도와주는 Create 버튼만 보인다. 유니티 엔진에서 애니메이션 클립을 직접 만들기 위해서는 이 버튼을 사용하면 된다. 이 버튼을 클릭한다.

 

 

 

 

그러면 애니메이션 클립 생성 및 저장을 위한 대화상자가 뜨는데 CubeRotating.anim 이라는 이름으로 애니메이션 클립을 하나 생성하자.

 

 

애니메이션 클립이 생성되면 애니메이션 창에 타임라인이 표시된다.

 

  

이제 큐브가 회전하는 애니메이션을 추가하기 위해서 Add Property 버튼을 누르고 Transform 항목의 Rotation의 + 버튼을 눌러준다.

 

 

로테이션 프로퍼티가 추가되면 타임라인의 1초 지점을 클릭하고 Rotation.y 값을 360으로 설정한다.

 

 

그 다음 애니메이션 창의 재생 버튼을 눌러보면 화면에 배치된 큐브가 회전하는 것을 확인할 수 있다.

 

유니티 엔진에서 직접 만들어지는 애니메이션 클립은 대부분 이런 과정을 통해서 만들어지며 일반적으로 간단한 애니메이션이나 UI 애니메이션을 만들 때 사용되는 경우가 많다.

 

 

 

 

 

애니메이터 컨트롤러

 

애니메이션 클립에 대해서 설명했으니 이제 애니메이터 컨트롤러에 대해서 이야기할 차례이다. 앞서 이야기 했듯이 애니메이션 클립이 한 동작에 대한 애니메이션이라면 애니메이터 컨트롤러는 여러 애니메이션 클립을 모아서 오브젝트가 어느 시점에 어떤 애니메이션을 어떻게 재생할지 결정하는 역할을 한다.

 

  

애니메이터의 기본적인 구성요소는 스테이트(State), 트랜지션(Transition), 파라미터(Parameter) 이렇게 세 가지이다.

 

 

스테이트(State)

 

 

스테이트는 일반적으로 애니메이터에서 애니메이션 클립을 담고 있는 하나의 상태로, 지금 어느 애니메이션 클립이 재생되어야 하는가를 표현한다.

 

 

스테이트 중 하나를 클릭하여 선택하면 인스펙터 창에서 현재 선택된 스테이트의 정보를 확인하고 수정할 수 있다. 스테이트의 이름을 바꿀 수 있는 것은 물론이고 Motion 프로퍼티에는 현재 스테이트가 재생할 애니메이션 클립을 설정할 수 있고 Speed 프로퍼티를 통해서 애니메이션이 재생될 속도 역시 설정할 수 있다.

 

또한 위 예시 이미지에서 배치된 스테이트들은 애니메이터의 가장 기본적인 스테이트들로 스테이트당 하나의 애니메이션 클립을 담는다. 애니메이션 클립 하나를 담는 스테이트 이외에도 파라미터 값에 따라서 여러 애니메이션을 블랜딩해주는 블랜드 트리나, 여러 스테이트들을 담을 수 있는 서브-스테이트 머신이 있다. 추가적인 내용은 다른 파트에서 다루도록 하겠다.

 

특수한 스테이트

 

예시로 보여진 애니메이터 컨트롤러의 그래프를 보면 일반적인 노드는 회색의 사각형으로 표시되고 있는데, 그 외에 특별한 형태의 노드를 볼 수 있다. 

 

 

첫 번째는 엔트리(Entry)다. 엔트리는 애니메이션이 처음 시작될 때의 진입점을 의미한다.

 

 

이 엔트리에서 제일 처음으로 연결된 노드는 주황색으로 표시되며, 게임오브젝트가 활성화되어 애니메이션이 시작되면 이 주황색으로 표시된 애니메이션부터 재생이 시작된다.

 

 

노드를 기본 스테이트로 만들기 위해서는 기본 스테이트로 만들고자 하는 노드를 우클릭하고 [Set as Layer Default State] 항목을 선택하면 된다.

 

 

두 번째는 모든 스테이트(Any State) 노드이다. 이 노드는 애니메이터가 어떤 애니메이션을 재생하고 있는 상태이던 간에 트랜지션의 조건이 만족되면 무조건 다음 스테이트로 넘어가서 애니메이션을 재생하게 만든다.

 

예를 들어 캐릭터가 걷는 중이든, 가만히 서있는 중이든, 아니면 포션을 마시는 중이었든, 큰 데미지를 입어서 죽으면, 바로 Die 스테이트로 넘어가도록 하는 것이다.

 

 

마지막으로 엑시트(Exit) 노드이다. 엑시트 노드는 애니메이터의 흐름이 한 번 끝났음을 의미하고, 엑시트 노드를 통과하면 엔트리 노드로부터 다시 애니메이터의 흐름이 다시 시작된다.

 

 

파라미터(Parameter)

 

 

애니메이터의 파라미터는 한 애니메이션에서 다른 애니메이션으로 전환되는 조건이 되는 변수의 역할을 한다. Parameters에서 + 버튼을 누르면 추가할 파라미터의 종류를 선택할 수 있다. 파라미터의 종류로는 Float, Int, Bool, Trigger가 있으며 Float는 소수점을 나타낼 수 있는 실수, Int는 정수, Bool는 참/거짓을 표현하는 논리 변수이며, Trigger는 Set되면 True가 되고 해당 Trigger가 걸린 트랜지션을 통과하면 자동으로 False로 바뀌는 타입이다.

 

 

트랜지션(Transition)

 

 

트랜지션은 애니메이터에서 스테이트와 스테이트 사이를 이어주는 것이다. 스테이트 사이를 이어줄 때, 애니메이션이 어느 방향으로 흘러갈지 방향을 정할 수 있다. 그 외에도 트랜지션을 선택하면 인스펙터 창을 통해서 선택된 트랜지션이 실행될 조건이나, 한 스테이트에서 다른 스테이트로 넘어갈 때 애니메이션을 어떻게 블랜딩해줄 것인지 등을 설정할 수 있다.

 


 

이 외의 애니메이션과 관련된 포스트는 애니메이션 카테고리에서 확인할 수 있다.

 

 

반응형

Tutorial (6)

 

게임 오브젝트와 컴포넌트

 

작성 기준 버전 :: 2018.3.2f1

 

[본 튜토리얼의 내용은 유튜브 영상을 통해서 확인하실 수도 있습니다]

 

이번 섹션에서는 게임 오브젝트와 컴포넌트에 대해서 알아보자.

 

게임 오브젝트(Game Object)

 

게임 오브젝트는 유니티 엔진에서 가장 기본이 되는 개념으로 캐릭터와 바닥에 떨어진 아이템, 배경으로 배치된 건물이나 소품, 폭발하면서 발생하는 이펙트, 빛을 밝히는 광원, 모든 장면을 찍는 카메라까지 씬에 배치되는 모든 것은 게임 오브젝트이다.

 

기본적인 게임 오브젝트에 나중에 설명할 컴포넌트를 추가로 붙임으로써 게임 오브젝트가 캐릭터가 되느냐, 아이템이 되느냐, 아니면 간단한 배경이 되느냐를 결정하게 된다.

 

 

게임 오브젝트는 기본적으로 이름(Name - "GameObject"), 태그(Tag - "Untagged"), 레이어(Layer - "Default")를 가지고 있다. 이를 응용해서 나중에 원하는 오브젝트를 찾거나 할 수 있다.

 

 

컴포넌트(Component)

 

컴포넌트는 게임 오브젝트에 붙일 수 있는 다양한 기능을 가진 구성요소들로, 비어있는 게임 오브젝트에 어떤 컴포넌트를 붙이느냐에 따라서 그 게임 오브젝트의 역할이 달라진다.

 

트랜스폼 컴포넌트(Transform Component)

 

모든 컴포넌트 중에서 트랜스폼(Transform) 컴포넌트는 모든 게임 오브젝트에 기본으로 부착되며 제거할 수 없다.

 

 

이 트랜스폼 컴포넌트는 해당 게임 오브젝트가 씬에 어느 위치에, 얼마나 회전되어서, 어떤 크기로 배치되어 있는지를 정하는 컴포넌트이다.

 

기타 컴포넌트

 

게임 오브젝트에는 여러 컴포넌트를 붙일 수 있고 어떤 컴포넌트를 붙이느냐에 따라서 게임 오브젝트의 역할이 달라진다.

 

 

게임 오브젝트에 Light 컴포넌트를 붙이면 광원이 되고 Camera 컴포넌트를 붙이면 게임 내에서 씬을 보여주는 카메라가 된다. 이렇게 유니티에서 기본적으로 제공하는 컴포넌트 이외에도 개발자가 유니티 스크립트 API를 이용해서 직접 컴포넌트를 만들어서 게임 오브젝트에 붙일 수도 있다.

 

컴포넌트 추가하기

 

컴포넌트를 추가할 게임 오브젝트를 선택하고 인스펙터 창에서 Add Component 버튼을 누르면 게임 오브젝트에 추가할 수 있는 컴포넌트들이 보여진다. 이 중에서 게임 오브젝트에 추가할 컴포넌트를 선택하면 된다.

 

 

커스텀 컴포넌트

 

유니티에서 기본적으로 제공하는 기본적인 컴포넌트 이외에도 개발자가 직접 컴포넌트를 만들어서 게임 오브젝트에 붙일 수도 있는데 대부분의 실제적인 게임 기능을 하는 시스템들은 커스텀 컴포넌트로 만들어지고 게임 오브젝트에 추가될 것이다.

 

 

커스텀 컴포넌트를 만드는 방법은 프로젝트 뷰에서 우클릭한 뒤 Create>C# Script 항목을 선택하면 된다.

 

 

그러면 NewBehaviourScript라는 이름으로 C# 스크립트 파일이 생성된다.

 

 

이렇게 생성한 컴포넌트는 다른 컴포넌트와 마찬가지로 컴포넌트를 붙일 게임 오브젝트를 선택하고 Add Component 버튼을 누른 뒤 추가한 컴포넌트의 이름을 검색해서 붙일 수 있다.

반응형

유니티 애니메이션 레이어(Animation Layer) 사용하기

 

 

 

지난 애니메이션 섹션에서는 비슷하지만 방향성이 다른 동작, 혹은 비슷하지만 속도가 다른 동작을 섞는데 사용하는 애니메이션 블랜드(Animation Blend)에 대해서 이야기해 보았다. 이번 섹션에서는 애니메이션 위에 일정 부분에 애니메이션을 덮어씌우는 애니메이션 레이어(Animation Layer)에 대해서 배울 것이다.

 

지난 애니메이션 블랜드 섹션 :: http://wergia.tistory.com/54

 

애니메이션 레이어는 여러 종류의 게임에서 이용될 수 있지만, 대표적으로는 FPS나 TPS 형식의 게임에서 주로 이용될 수 있다. 이러한 형식의 게임의 경우 캐릭터는 한 순간에 한 가지 행동만을 하는 것이 아니라, 하나 이상, 일반적으로는 두 개 정도의 행동을 하는 일이 많다. 간단하게 예를 들자면 총 같은 화기를 사용하는 FPS 게임이라면 캐릭터는 달리거나 걷는 동시에 총을 쏠 수도 있고, 단검을 휘두를 수도 있으며, 탄창을 교체하기도 한다. 앞서 이야기한 행동들을 하기 위해서 걸음을 멈추는 경우는 거의 없다. 평소에는 상체와 하체 모두 달리는 애니메이션을 취하지만, 달리는 도중에 다른 행동을 취한다면 하체는 여전히 달리는 모션을 출력하지만, 상체는 총을 쏘거나, 단검을 휘두르거나, 탄창을 교체하는 애니메이션을 출력하게 되는 것이다.

 

물론 이러한 애니메이션들을 일일이 만들어 내는 방법도 있지만 이것은 너무 비효율적인 일이다. 만약에 애니메이션 레이어를 사용하지 않고 모든 애니메이션을 만든다면, 가만히 서서 위의 세 가지 행동을 하는 애니메이션, 걸으면서 다른 행동을 하는 애니메이션, 달리면서 행동을 하는 애니메이션 등을 모두 만들어내야 할 뿐만 아니라, 만약 점프하면서 폭탄을 던지는 모션을 만들고자 한다면 점프하는 모션 중 어느 타이밍에 폭탄을 던지는 모션을 추가해야할지 골머리를 앓게 될 것이다.

 

하지만 애니메이션 레이어를 사용하게 된다면, 걷는 애니메이션, 달리는 애니메이션, 서있는 애니메이션, 점프 애니메이션, 그리고 각각의 행동을 취하는 애니메이션 정도만 만든다면 위에서 설명한 표현들을 손쉽게 할 수 있게 된다.

 

 

이번 예시를 들기 위해서 지난 애니메이션 블랜드 섹션에서 사용했던 달리기 모션과 함께 이번에 간단하게 만든 팔을 휘두르는 애니메이션을 사용할 것이다. 공격이라고 보기엔 귀엽지만 공격 모션이다. 애니메이션 레이어와 달리는 모션, 그리고 가만히 서서 공격하는 모션만 있다면 달리면서 공격하는 모션을 만들 수 있다.

 

애니메이션 레이어 사용법을 배우기 위해 다음의 튜토리얼을 따라해보도록 하자.

 

 

1. 애니메이션 레이어에 사용할 Animator Controller를 생성하고 그 이름을 Animation Layer라고 짓도록 하자.

 

 

2. 생성한 애니메이터 컨트롤러를 열면 다음과 같이 빈 애니메이터 컨트롤러 창이 보일 것인데 그 중에 Layers라는 항목이 있을 것이다. 그 항목을 선택하면 Base Layer가 있는데 이 레이어는 애니메이션에서 기본적으로 제공하는 레이어이다. 이 레이어의 이름을 바꿀 수도 있고 나중에 다른 레이어를 추가한다면 기본 레이어를 삭제할 수도 있다.

 

3. 기본적인 달리기 애니메이션을 애니메이터 컨트롤러에 추가한다. 그리고 이 애니메이터 컨트롤러를 씬에 추가한 캐릭터의 애니메이터 컴포넌트에 넣고 플레이 버튼을 누르면 이 박스맨은 계속해서 달리기만 할 것이다.

 

4. 이 다음 작업은 아바타 마스크(Avatar Mask)를 생성하는 것이다. 이 아바타 마스크는 애니메이션 레이어를 사용할 때, 위에 덮어쓴 애니메이션이 적용될 본을 지정하는 것으로, 해당 레이어에서 원하는 본만 애니메이션이 작동하고 그 외의 본은 그 아래 레이어의 애니메이션을 작동하도록 만드는 것이다.

 

5. 생성한 아바타 마스크를 열어보면 Humanoid 방식과 Transform 방식이 있는 것을 알 수 있다. 휴머노이드 방식의 경우는 사진을 보면 알다시피 일반적인 사람형태의 본에 대해서 손쉽게 마스크를 지정할 수 있게 하는 것이고, 트랜스폼 방식은 직접 만든 특별한 형태의 본을 가져와서 원하는 애니메이션이 적용될 본을 직접 선택하는 방식이다.

 

6. 이번엔 None이라고 비어있는 Avatar 란에 직접 만든 박스맨의 본을 가져와야 한다. 이 본은 BoxMan@Attack을 열어보면 목각인형 상체 모양의 BoxMan@AttackAvatar를 볼 수 있는데 이것을 끌어와서 넣어주면 된다. 그리고 Import skeleton 버튼을 클릭하면 박스맨에 적용된 본들이 아바타 마스크의 인스펙터 창에 표시된다.

 

7. 이번 섹션의 작업에서 우리가 동작하기 바라는 것은 왼팔 하나뿐이다. 박스맨의 본들 중에 왼팔에 해당하는 본은 Bone005(mirrored)이다. 이 본만이 움직이길 원하기 때문에 Bone005(mirrored)를 제외한 모든 본의 체크를 꺼준다.

 

8. 이제 아까 만든 AnimationLayer 애니메이터 컨트롤러로 돌아와서 Layers 항목의 아래 쪽에 +버튼을 클릭하여 새 레이어를 만들고 그 이름을 UpperBody로 변경한다.

 

9. 잠시 Parameters 항목으로 넘어가서 애니메이터 컨트롤러의 매개변수에 "Attack"라는 이름의 트리거를 생성한다.

 

10. UpperBody 레이어에 NoneAttack 상태를 만들고 애니메이션은 비워둔다. 아무것도 하지 않는 동작이기 때문에 비워두는 것이다. 만약 아무것도 하지 않는 동작이기 때문에 아래쪽의 베이스 레이어와 맞춰서 달리는 동작으로 해줘야 한다고 생각할 수 있는데 그런 식으로 달리는 애니메이션을 넣었다가는 하체의 달리는 모션과 상체의 팔 휘두르는 모션의 싱크가 일치하지 않게되는 현상을 겪을 수도 있다.

 

11. Attack 상태를 추가하고 Attack 애니메이션을 넣어준 다음에 NoneAttack 상태에서 Attack 상태로 넘어가는 조건에 아까 만든 Attack 트리거를 넣어준다. 이렇게 함으로서 이제 애니메이션 컨트롤러에 Attack 트리거 신호가 들어오면 캐릭터는 어택 모션을 취하게 될 것이다(설정에 실수를 했는데 Inspector 창에서 Has Exit Time의 체크는 해제해야 한다).

 

12. 다음 작업은 레이어 설정을 해주는 것이다. 레이어 이름 옆에 톱니바퀴 버튼을 클릭하면 레이어 옵션을 볼 수 있는데 여기서 두 가지를 설정해주면 된다. 첫 번째는 Weight 값인데 이 값은 현재 레이어와 아래 레이어의 애니메이션 비중을 의미한다. 1에 가까울 수록 캐릭터는 현재 레이어에 가까운 모션을 취한다. 즉, 1값이면 캐릭터는 현재 레이어의 애니메이션만 취한다. 그리고 Mask 옵션인데 이것은 애니메이션을 출력하고자 하는 부위만 출력하도록 해주는 것이다. 아까 전에 만든 왼팔만 적용되는 마스크를 넣어준다.

 

애니메이션 레이어에 필요한 모든 설정을 끝냈다. 이제 플레이 버튼을 클릭하고 캐릭터의 달리는 모션이 출력되는 도중에 Attack 트리거를 켜보면 다음 이미지와 같이 박스맨 캐릭터가 달리기 모션을 취하면서도 왼팔만은 정상적으로 휘두르는 것을 볼 수 있다.

 

 

 

이것처럼 애니메이션 레이어를 사용하면 애니메이션 작업양을 획기적으로 줄이면서도 다양한 동작을 취하도록 할 수 있다. 하지만 이 예시는 매우 간단하게 제작된 본과 모델링을 사용하는 것으로, 일반적으로 게임 제작에 사용되는 복잡한 형태의 본과 모델을 사용하는 경우에는 본의 구조나 리깅된 면의 정상적인 움직임을 위한 면밀한 연구가 필요할 것이다.

 

마지막으로 다음의 링크에서 위의 예시로 제작된 간단한 애니메이션 레이어 예제를 받을 수 있다.

 

AnimaitonLayerExample.zip
다운로드

 

반응형
  1. 오 좋은글! 2017.06.20 02:41

    오 좋은글 감사합니다!

  2. 김매기 2017.07.24 12:23

    포스팅 감사히 잘봤습니다. 유니티 초보인데도 아주쉽게 이해가 잘가요! 매우 깔끔합니다

+ Recent posts