게임에 존재하는 오브젝트가 현실의 사물처럼 움직이도록 움직임을 부여하는 기능.
오늘은 유니티에서의 Animator 사용법을 알아보고
평소에 스쳐 지나갔던 게임 환경에선
애니메이션의 어떤 기능이 적용되었을지에 대해 알아보겠다.
기능 소개가 대부분이라 요약할 게 없다.
패스
처음 유니티를 접했을 때 생겼던 의문점 중 하나가
컴포넌트를 찾을 때 Animation, Animator 가 서로 나눠져 있어
'둘 중에 뭘 써야 되는 거지?' 생각했던 적이 있다.
그래서 첫 시작으로 애니메이션과 애니메이터 컴포넌트의 기능부터 알아보겠다.
단일 애니메이션을 적용하기 위한 레거시 컴포넌트

(주로 구형 프로젝트나 단순 움직임에 사용)
오브젝트에 직접 애니메이션 클립을 붙여 재생하는 방식이며
전환 / 이벤트 연동 등 고급 기능 사용이 제한적이다.
예전 코드와의 하위호환성을 위해 남아 있다고 봐도 될 것 같다.
유니티에서 권장하는 애니메이션 구현용 컴포넌트.
애니메이션 컴포넌트와 달리 클립을 직접 연결하여 사용하지 않음.
대신 Animator Controller 라는 제어 에셋을 연결하여 사용.

위부터 순서대로 각각의 기능부터 알아보자.
기능이 많은 편이기에 일단 기억해두고
실사용 시 헷갈리면 이 글을 다시 읽어보도록 하자.
애니메이션 클립과 상태 간의 전환 로직을 정의하는 Animator Controller를 연결
애니메이션 데이터를 실제 캐릭터 모델의 뼈대(Bone) 구조에 매핑하는 설정 파일을 연결
애니메이션 클립에 포함된 루트(Root) 오브젝트의 위치 및 회전 이동 정보를
게임 오브젝트에 적용할지 여부를 결정하는 기능
체크 시, 애니메이션 자체가 캐릭터의 이동을 제어
Ex) Walk 클립이 실제로 캐릭터를 이동시킴.
애니메이션 업데이트를 물리 엔진의 업데이트(FixedUpdate)와 동기화할지 여부를 설정
Rigidbody 컴포넌트가 있는 오브젝트의 애니메이션을 물리 기반으로 정확하게 제어할 때 유용
Animator가 어떤 주기로 업데이트될지 명시적으로 설정

여기서 의문이 생겼다.
4) 의 Animate Physics 와
5) 의 Mode -> Fixed 의 차이점을 모르겠어서 질문 및 검색
결론부터 말하자면 기능은 동일하다고 한다.
Animator.updateMode = AnimatorUpdateMode.AnimatePhysics
둘 다 내부적으로 업데이트 모드를 위와 같이 변경해 줌...
열심히 찾아봤다가 좀 허무해지긴 했으나
같은 기능이 어찌하여 두 개나 존재하게 된 경위가 궁금해져 알아보기 시작했다.
아래는 찾아보면서 발견한 이전 인스펙터 사진들을 시간순으로 나열한 것.



위 사진을 보면 알 수 있듯이
Unity 예전 버전엔 Animate Physics 체크박스가 있었다가?
비교적 최근 버전에선 Update Mode에 편입되었고?
지금 사용중인 신버전에선 체크박스가 부활하고
Update Mode에 편입되었던 자리엔 동일한 기능의 Fixed가 추가됨.
Animate Physics 체크박스가 부활한 이유는
기존 Animator 설정과의 하위호환성을 위해 유지하는 거라고 한다.
추후에 애니메이션과 물리엔진의 동기화가 필요하다면
Update Mode -> Fixed 로 설정하도록 하겠다.
고민 해결!
오브젝트가 카메라 시야밖에 있을 때
애니메이션 업데이트를 처리하는 방식을 결정하여 성능을 최적화하는 기능.

기능은 전부 확인했는데
마지막 Culling Mode를 보면서 떠오른 영상이 있어서 가져왔다.

썸네일에서도 사용한 사이버펑크2077 T-pose 버그.
필자도 출시 당시에 사전예약으로 구매하였는데
튜토리얼 끝난 뒤 밖에 나와서 그림자를 보자마자 저렇게 T-pose를 하고 있어서 짜게 식은 기억이 있다.
물론 제작사 CDPR에선 Unity 엔진이 아닌 자사 자체 엔진을 사용한 걸로 알고 있다.
다만 플레이어의 시야에서 벗어난 오브젝트를 관리하여
성능을 최적화 하고 있는 예시로선 알맞다고 생각하여 이걸 떠올리며 기억하기로 했다.
이런 유쾌한 결과가 나온 원인을 이번 배움을 통해 생각해보면
시야 밖에서의 최적화를 위해
1인칭 시점에서 유저에게 안 보이는 플레이어의 기본 상태를 T-pose 로 구현한 듯 하다.
(아님 말고)
그렇다면 이런 상황을 방지하기 위해선 어떻게 해야 할까?
일단 T-pose가 되는 것 외에도 단검을 던질 때의 자세도 이상하다.
관절이 던지는 방향과 다르게 꺾이는 것이 그림자에 보인다.
이런 기괴한 움직임의 원인은 이전에 들어 알고 있다.
1인칭 시야에서의 팔다리의 움직임을 자연스럽게 만들기 위해 시야 밖의 관절을 이리저리 꺾어대는 것.
아래는 예시

붕괴 스타레일의 라파라는 캐릭터의 1인칭 시점
팔이 굉장히 역동적으로 움직인다.

3인칭 시점
ㅋㅋㅋㅋㅋㅋㅋㅋ
아무튼 이 상태에서 1인칭의 역동성을 유지하며 T-pose를 가려야 하는데
나는 그림자용 애니메이션(혹은 모델링)을 따로 제작할 것 같다.
다만 성능을 유지하며 구현할 방법을 모르겠다.
이 버그를 고치는 건 나에겐 아직 어려워 보인다.
최적화 관련해서 배우다 보면 방법이 떠오를테니 일단 넘기겠다.
이제 Animator Controller View 를 알아보겠다
애니메이션의 상태와 연결된 전환 로직을 보여주는 화면.
여기서 좌측 상단의 Parameters, Layers 를 알아보겠다.

사진처럼
애니메이션 간의 전환 방향을 시각적으로 표현하며
Conditions을 통해 전환에 필요한 조건을 지정 가능
체크 시, 모션이 다 끝나야 다음 모션을 진행
후딜레이 긴 스킬 등에서 활용 가능
행동 변화에서의 조건을 정해주는 변수를 모아두는 패널.

C# 스크립트 작성하며 변수부터 적어두는 거랑 비슷하다.
총 4종류의 변수를 지정할 수 있다.
Animator 시스템에서 여러 애니메이션을 서로 분리하여 동시에 적용하고 블렌딩할 수 있게 해주는 계층 구조
Base Layer = 기본 레이어
Base Layer + 추가 Layer = 최종 결과
기본 기능을 간단히 알아보자.
Weight: 가중치, 1에 가까울 수록 Base를 가려줌, Avatar Mask 필요

Avatar Mask: 아바타 전부가 아닌 일부만 사용할 수 있도록 해주는 것.

Blending
- Override: 해당 캐릭터 부위(예: 상체, 하체, 팔)의 최종 포즈를 전적으로 결정
- Additive: 기존 애니메이션 포즈에 해당 애니메이션 클립의 "변화량(Delta)"을 더해서(Add) 적용

Sync: Source Layer 와의 상태구조, 애니메이션 재생 시간 등을 동기화

Upper Layer에서 가중치 1, 상체만 사용하도록 지정하여
Base Layer와 동시에 출력되도록 설정.

비교적 간단함.
하나 이상의 파라미터 값에 따라 여러 애니메이션 클립을
실시간으로 부드럽게 섞어서(Blending) 재생할 수 있게 해주는 기능
활용처의 예시로
"moveSpeed에 따라 다른 모션이 나오게 하고 싶어요"
이럴 때 쓰기 좋은 기능.
다시 말해

이걸 딸깍으로 만들어주는 기능!
블렌드 타입 1D의 사용법을 알아보겠다.
나머진 추후에 배울 예정.

(새로 제작해도 됨)
이후 Blend Tree 노드를 더블 클릭하여 편집 모드로 진입.



이후 각 클립이 블렌딩 될 Threshold(임계값)을 설정.
예시)
Threshold: 0 = Idle
Threshold: 2 = Walk
Threshold: 5 = Run
Threshold: 8 = Naruto Run
임계값이 1일 경우엔 Idle과 Walk가 반반 섞여서 재생.
임계값이 6.5일 경우엔 Run과 NarutoRun이 반반 섞여서 재생.
이 정도만 알아둬도 굉장히 유용한 기능이니 자주 써 봐야겠다.
둘 다 부드러운 보간을 위한 기능이지만
SmoothStep의 경우 하나의 보간값을 통해 시간과 속도를 고려하지 않고 보간,
SmoothDamp의 경우 목표 위치까지의 속도와 가속도를 고려하여 보간
따라서 현재 위치, 목표 위치, 가속도와 시간의 파라미터 값을 필요로 함.
예시) SmoothDamp
Vector2 newPosition = Vector2.SmoothDamp
(
currentPosition, // 현재 값
moveInput, // 목표 값
ref smoothVelocity, // 속도를 추적하고 업데이트할 변수 (ref)
smoothTime // 목표에 도달하는 데 걸리는 시간
);
Level Of Detail
게임 오브젝트의 디테일 수준을 관리하는 기능.
거리에 따라 디테일을 낮춰서 최적화를 수행함.
예시 사진

공식문서 에서 가져왔다.
맵이 넓고 방대한 게임에서 자주 찾아볼 수 있는 기능인 듯 하다.
멀어질 수록 LOD 레벨이 높아지고 아주 멀어질 경우엔 오브젝트를 출력하지 않게 만든다.
최적화가 필요한 경우에 유용한 기능이라 알아두면 좋을 듯.
오늘은 코드 작성보다 유니티에서의 애니메이션 기능에 대해 배운 시간이 훨씬 길다.
당장 전부 외울 필요는 없다고 생각한다.
알아만 두고 어떠한 기능이 필요할 때마다 찾아보자.