Unity Chapter 9-3. 애니메이션 : 애니메이터 레이어, 마스크, IK
카테고리: Unity Lesson 1
태그: Unity Game Engine
인프런에 있는 이제민님의 레트로의 유니티 C# 게임 프로그래밍 에센스 강의를 듣고 정리한 필기입니다. 😀
🌜 [레트로의 유니티 C# 게임 프로그래밍 에센스] 강의 들으러 가기!
Chapter 9. 유니티 애니메이션
Asstes Store에서 “Unity-Chan!”을 Import 해주었다.
🔔 애니메이터 레이어
Layers
: 여러개의 상태 머신(FSM)을 동시에 동작하게 해준다. 1개의 상태 머신 내에서는 1개의 상태만 동작할 수 있다. 그러나Layers
로 여러개의 상태 머신을 동시에 돌릴 수 있기 때문에 여러개의 상태를 동시에 동작시킬 수 있다.
- 두 레이어에서 동작에 있어 겹치는 부분이 있다면 최종적으로 가장 아래에 있는 레이어가 덮어 씌운다.
- 위의 사진를 예로 들어 만약 Face Layer에 공격하는 신체 동작 애니메이션이 실행된다면 Base Layer의 애니메이션이 실행이 안된다. 묻혀서!
- weight 값이 높을수록, 즉 가중치가 높을 수록 덮어 씌우는 정도가 높아진다.
- 1에 가까울 수록 아예 덮어 씌워버리는 정도가 높아짐.
- 따라서 레이어별로 각자 역할을 명확하게 나누어야 한다. ⭐
- ex) Move Layer (움직임에 대한 애니메이션만) Face Layer (표정에 대한 애니메이션만)
- “손, 팔, 몸통”과 “얼굴 표정”은 서로 동작이 겹칠 일이 없다.
- ex) Move Layer (움직임에 대한 애니메이션만) Face Layer (표정에 대한 애니메이션만)
- Face Layer의 weight을 1로 해준 후 화난 표정 애니메이션을 추가하니 두 레이어가 덮어 씌우는 것 없이 두 레이어가 동시에 잘 동작하는 것을 볼 수 있다.
- “손, 팔, 몸통”과 “얼굴 표정”은 서로 동작이 겹칠 일이 없으므로.
마스크
Mask
를 통해서 레이어가 어떤 영역에 대해서만 애니메이션을 적용할지 결정한다.
- 몸통의 상체 애니메이션을 담당할 Upper Layer도 만들어주었고 순서는 Base - Upper - Face로 하였다.
- Upper Layer의 weight을 1로 해준다.
마스크 만들기
- 📂Assets 빈공간 우클 - Create - Avatar Mask
- 이름은
Upper Mask
- 하체 부분은 체크 해제하고 상반신만 체크해준다.
- Upper Layer의 톱니바퀴 버튼을 누르고 Mask 슬롯에 이를 넣어준다.
- 이름은
- Face Layer에는 미리 만들어져있는 Unity Chan 에셋의
face only mask
를 마스크로 넣어준다. - Blending 값으로 Override는 아예 덮어씌우는거고 Additive는 적절히 섞이게끔.
- Override : 아래에 있는 Layer들을 다 덮어 씌워버려서 아래 Layer의 애니메이션은 실행되지 않음
- Additive : 아래에 있는 Layer들의 애니메이션과 적절히 섞여서 함께 실행됨!
- LOOSE 애니메이션 클립을 Upper Layer에 드래그 앤 드롭하여 State 추가해준다.
레이어 덮어 씌우는 구조
- 현재 세 Layer 모두 weight값이 1인 상태
- 👉 자신보다 위에 있는 Layer들을 완전히 덮어 씌운다.
- 게임을 실행시키고 방향키를 누르면
- Upper Layer가 Base Layer를 덮어씌워
- 상반신만 덮어씌워져 상반신은 LOOSE 애니메이션을 취하지만
- 하반신은 방향키대로 걷고 있는 애니메이션을 취한다.
- Face Layer는 두 Layer를 덮어 씌우므로 화난 얼굴 표정 애니메이션은 계속 유지가 된다.
- Upper Layer가 Base Layer를 덮어씌워
🔔 IK (Inverese Kinematic)
IK
: 어떤 위치를 중심으로 관절의 위치를 역계산하는 것. 물체의 위치가 어디든 상관없이 거기에 맞춰서 시선이나 팔의 위치가 결정될 때 많이 쓴다.
Sphere인
Ball
이름의 오브젝트를 만들어 게임이 시작되면unitychan
이 이Ball
을 잡는 애니메이션을 취하게 해보자.
- 👉
Ball
오브젝트의 위치를 중심으로 애니메이션의 관절의 위치를 결정한다.
📜PlayerController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class PlayerController : MonoBehaviour
{
public Animator anim;
public Transform target;
void Update()
{
if(Input.GetButtonDown("Jump"))
{
anim.SetTrigger("Jump");
}
float verticalInput = Input.GetAxis("Vertical");
float horizontalInput = Input.GetAxis("Horizontal");
anim.SetFloat("Speed", verticalInput);
anim.SetFloat("Horizontal", horizontalInput);
}
void OnAnimatorIK()
{
anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, 0.5f);
anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, 0.5f);
anim.SetIKPosition(AvatarIKGoal.LeftHand, target.position);
anim.SetIKRotation(AvatarIKGoal.LeftHand, target.rotation);
anim.SetLookAtWeight(1.0f);
anim.SetLookAtPosition(target.position);
}
}
- public Transform target;
- 어떤 오브젝트를 중심으로 관절을 꺾을지.
Ball
오브젝트를 잡게 할 것이므로Ball
오브젝트의 중심 위치가 필요하므로 선언했다.- 슬롯에
Ball
오브젝트를 드래그 앤 드롭 해주어야 한다.
- void OnAnimatorIK()
- 이벤트 함수.
- IK 정보가 갱신될때마다 유니티는 OnAnimatorIK 메세지를 뿌린다.
- 애니메이터가 붙어있는 오브젝트만 이 이벤트 함수를 동작시킬 수 있다.
- anim.SetIKPositionWeight(AvatarIKGoal.LeftHand, 1.0f);
- IK의 우선순위를 결정해준다.
- 두번째 인수가 0.0에 가까울 수록 IK가 덜 적용되며 1.0에 가까울 수록 IK가 더 강하게 적용된다.
- 위치(Position) 면에서 IK의 대상이 되는 아바타는 “왼쪽 손”이다.
- anim.SetIKRotationWeight(AvatarIKGoal.LeftHand, 1.0f);
- IK의 우선순위를 결정해준다.
- 두번째 인수가 0.0에 가까울 수록 IK가 덜 적용되며 1.0에 가까울 수록 IK가 더 강하게 적용된다.
- 회전(Rotation) 면에서 IK의 대상이 되는 아바타는 “왼쪽 손”이다.
- anim.SetIKPosition(AvatarIKGoal.LeftHand, target.position);
- 관절을 꺾어 해당 타겟의 위치로 이동시킨다.
- anim.SetIKRotation(AvatarIKGoal.LeftHand, target.rotation);
- 관절을 꺾어 해당 타겟의 위치로 회전시킨다.
- anim.SetLookAtWeight(1.0f);
- 시선에 있어 IK의 우선순위를 결정해준다.
- 0.0에 가까울 수록 IK가 덜 적용되며 1.0에 가까울 수록 IK가 더 강하게 적용된다.
- anim.SetLookAtPosition(target.position);
- 시선을 해당 타겟의 위치로 이동시킨다.
IK Pass
- 신체 애니메이션을 담당하는 Base Layer와 Upper Layer의 IK PASS를 체크해주어야 IK를 받을 수 있다.
- (체크해주지 않으면 무시함)
- IK가 적용된 왼손은
Ball
오브젝트를 향해 뻗어 있는 것을 볼 수 있다.- 반면에 IK가 적용되지 않은 오른손은 여전히 LOOSE 애니메이션 동작을 취하고 있다.
🌜 개인 공부 기록용 블로그입니다. 오류나 틀린 부분이 있을 경우
언제든지 댓글 혹은 메일로 지적해주시면 감사하겠습니다! 😄
댓글남기기