Study/유니티

유니티 Animation / Animator

Privacy TT 2024. 1. 19. 19:39

애니메이션이 자체모션에 따라 트랜스폼이 이동되는 경우

해결방법은 두가지.

첫번째론 애니메이터에 Apply Root Motion을 체크 해제

두번째로는 해당 애니메이션을 찾아서 Root Motion Node를 <None>로 바꿔주면 위에 루트 트랜스폼 포지션항목이 여러가지 나오는데, 거기서 Bake Into Pose를 건드려주면서 이동제어를 할 수 있음.


Has Exit Time

해당 애니메이션의 모션이 종료된 후 이동할 것인지 아니면 즉시 이동할 것인지.

체크가 되어있다면 모션이 끝난후 움직이고 체크해제라면 조건이 충족되는 순간 바로 넘어감.


애니메이션을 사용하는 방법 두가지

  1. 애니메이터 컨트롤러를 이용한 GUI 방식
  2. 스테이트 패턴을 이용한 코드에서의 개별 호출방식

첫 번째 방법 - 애니메이터 컨트롤러 이용

장점은 뭐니뭐니해도 GUI로 되어있어 한눈에 들어온다는것.

숫자가 많지않다면 화살표로 이동경로를 다 알 수 있다는것.

단점은 반대로 한눈에 들어올정도로 적은 개수가 아닐경우 오히려 더 복잡해보이는것.

화살표연결과 파라미터 설정을 하나하나 다 해줘야한다는것.

애니메이션을 섞는 블랜딩이나 블랜드트리는 애니메이터컨트롤러에서밖에 안되는 것 같아서 애니메이터 컨트롤러를 써야만 하는 상황이 있을 수 있어보임.

예를 들어 이동속도에 따른 달리기모션이 걸을때 고정수치 A 달릴때 고정수치 B라면 그냥 걷기, 달리기 두가지 모션만 있으면 되지만 이동속도가 버프/디버프 등의 효과로 인해 다양하고 모션또한 다양하게 주고싶다면 애니메이션 블랜드를 사용해야되기 때문에 컨트롤러를 사용해야함.

두번째의 스테이트패턴을 이용한 호출방식 또한 애니메이션 컨트롤러에서도 유사하게 사용할 수는 있음. 어차피 스테이트패턴자체가 Int로 되어있는거에 String값을 붙이는거기때문에 그냥 해당 패턴을 인트로 받아서 사용하면 됨.

파라미터를 인트(스테이트 변수)로, 값은 이퀄로 해놓으면 스테이트 패턴에 따라 움직임.

다만 이건 만능은 아니고 특정 상황에 따라 하면 좋을듯.

예를 들어 Idle에서는 스킬로 바로 연결되지않고, BattlePaze라는 Bool값을 하나 넣어주던가 Battle Idle상태를 만들어둔뒤 거기에서 여러가지 스킬을 나눠놓고 그 스킬로 이동하는 조건 파라미터를 State 변수로 주는것. 이렇게하면 배틀페이즈가 아니라면 해당 state변수를 초기화해주지않아도 스킬을 마구 사용하지 않음.

두 번째 방법 - 코드에서 State 변수를 이용

일단 애니메이터 컨트롤러에 사용할 애니메이션 클립을 몽땅 넣는다.

그 뒤 코드에서 해당 애니메이션들을 전부 Enum으로 묶어준다.

그리고 해당 Enum의 State 변수를 만들고 이게 애니메이션 상태를 총지휘하는 하나의 길잡이가 되는것.

Animator.Play를 사용하면 뚝뚝 끊기는 문제가 있는데, CrossFade를 사용하면 해결.

State 변수를 프로퍼티로 만들어서 Set하는 부분에 Animator와 동기화를 하면 한층 편해짐.

상태가 바뀔 때 해당 애니메이션을 재생하는 방법으로.

장점이라면 애니메이션이 아무리 많아도 스테이트패턴에서 호출하는 방식이기때문에 덜 헷갈림

컨트롤러에서 애니메이션끼리의 연결을 해주지않아도 되서 편하고 파라미터값도 필요없음 (정확히 말하면 모든 화살표를 연결하고 그값을 Int(state)파라미터 하나로만 사용하는 방식이라 굳이 연결을 안해줘도 되는것

단점이라면 한눈에 보기 어려울거고 어떤 형태에서든 다른 애니메이션으로의 전환이 가능하게 되버림. 예를 들면 점프상태에서 달린다던가 스킬을 쓴다던가. 다만 이건 단점이라고만 하기엔 오히려 의도해서 써먹을만한 상황이 있을지도 모르겠다.

또 상태관리가 어려울 수 있음. 점프같은걸 하면 점프가 끝나고 자동으로 Idle로 돌아가는 그런게 안되서 코드로 끝나면 Idle상태로 바꿔준다던가 하는 작업을 따로 해야함

 


간단하게 휘두르는 무기장착

FBX파일에서 무기를 장착할 부위 - 손이나 팔 등등에 그냥 검이든 지팡이든 뭐든 쥐어주면 알아서 움직임에 따라 휘두르고 이것저것 다함.

이 방법에선 오히려 활같은게 가장 어려운 형태일듯?

 


애니메이션의 범용적 활용

휴머노이드 타입의 애니메이션이라면 모든 휴머노이드 타입의 모델에 대응되기때문에 어디서든 사용이 가능. 다만 모두고려가 안되어있기때문에 머리카락을 뚫는다던지 옷이랑 겹친다던지 하는 문제정도는 있다. 개별 수정이 필요한 부분.

 


Trangition 상태일 때는 애니메이션 전환이 되지 않음

두 클립 사이를 오갈 때 - 그러니까 애니메이터에서 Transitions 상태일때는 다른 화살표로 이동이 불가능하다.

발견한 계기는 Wait과 Move애니메이션을 오가는 사이에 Attack 애니메이션 클립을 실행시켰는데 실행이 안되는 타이밍이 있어서 이것저것 테스트 해보다가 알게됨.

해결방법은 별거없다. 그냥 트랜지션이 끝나고 애니메이션이 호출되게끔 하는수밖에…

Attack이 실행되고 끝나기 전까진 다른 클립으로 이동하지 않는 조건문을 처음에

if (playerAnim.GetCurrentAnimatorStateInfo(0).IsName("Attack"))
{
		return;
}

를 썼었는데 여기서 문제가 트랜지션 상태일 때 Attack 트리거를 발동시켰지만 정작 다음 업데이트문에서 Stateinfo를 체크할땐 아직 Attack클립이 실행되지 않은 상태라서 return이 안되고 그래서 그 아래의 아무입력도 없으면 Idle상태로 돌아가는 코드가 실행되서 아예 Attack이 씹혀버린 문제였음.

그래서 아래처럼 일단 애니메이션이 실행되기전까진 AttackState를 유지하다가 Attack클립의 종료 이벤트 호출에서 다시 SetInteger로 돌아가는걸로 해결했음.