본문 바로가기
프로젝트A

상태머신에 대해 알아보자

by IX. 2023/09/10 02:12:36

9.8

유한 상태 머신(FSM, Finite State Machine)

유니티에서는 애니메이터 컨트롤러라는 이름으로 등록돼 있다.

현재 듣는 강의는 기초적인 내용만 다루고 있어 조작감같은 게 영 좋지 못하다.

예를 들어 블럭같은 경우, 전이속도보다 조작속도가 빨라 상태를 받지 못하는 현상이 있었다.

방어키를 누르면 BlockOn이다. 방어키를 떼면 BlockOff이다. 이것이 트리거로 조작된다.

전에도 유니티를 공부하며 의문인 점이 이것이었다. 상태머신을 쓰면 어딘가 모르게 조작감이 후지고 완성도가 떨어져 보인다. 왜 그럴까.

 

일단 블럭을 했을 때 상태 변경이 확실히 되긴 하는 것일까?에 대한 확인이 필요하다.

그래서 스테이트를 확인하려 했더니

IsName()은 있는데 왜 name을 안줘?!

..해서 찾아보니, 유니티의 애니메이터는 현재 상태를 해시값으로 저장한다고 한다.

IsName()이 하는 일은 입력된 값을 해시로 변환해 현재 상태의 해시값과 비교한다음, 이것이 참인지 아닌지를 판단한다. 즉 문자열을 애초에 저장하지 않는다.

 

난 단지 키를 눌렀을 때 상태가 즉시 변하는가를 보고 싶었을 뿐인데 일이 커졌다.

별 수 없다. IsName()이라도 주니까 그걸로 비교해보자.

조사결과 유니티의 상태머신은 전이를 시작해도 스테이트를 바로 변경하지 않는다.

생각보다 더 한 참 후에 스테이트를 변경했다. 스테이트 변경은 전이가 끝난 후에 일어나는건가?

전이시간을 0초로 했을 경우, 바로 전이된다. 하지만 내가 원하는 건 키를 다다다다 눌렀을 경우의 빠른 트리거 변환이다.

전이속도를 기다릴 수 없다.

 

해서 자료를 좀 더 찾아보니 인터럽션이란 옵션이 있다.

Wait, I’ve changed my mind! State Machine Transition interruptions | Unity Blog

 

Wait, I’ve changed my mind! State Machine Transition interruptions | Unity Blog

Finally, for complete control, we can set the Interruption Source to “Current State Then Next State”, or “Next State Then Current State”. In that case, the transitions will be analyzed independently on one state, then the other. So, let’s assume

blog.unity.com

요약하면 스테이트 전이중이라도, 다음 스테이트에 우선시되는 전이가 있으면 취소하고 그걸로 넘어간다는 내용이다.

한 번 해보자.

오..되긴 되는데 두가지 문제가 있다.

  • 상태를 조건으로 걸 수가 없다. 그냥 애니메이션만 바뀌는 것이다. 즉 Idle->Block이 되는게 아니고 Idle->Idle이다. 돌아간다.  
  • 많이 누르면 고장난다. 

격투게임은 키조작이 거의 프레임단위로 일어나는데 고장나면 안되지!!

전이 시간이 0이라면 상관이 없지만, 난 보간된 움직임을 원한다. Idle->Block이 된 후, KeyUp을 했을 때 Block->Idle이 됐으면 좋겠다. 

 

처음엔 트리거가 문제인 줄 알았는데, 그렇지는 않았다. 흐음.

궁금한 게 하나 더 있다. 2개의 클립에 전이조건을 똑같이 걸었다면 어떤 게 발동될까?

점프에도 앉기조건을 걸었다. 그럼 캐릭터는 점프할까? 앉을까?

...아예 움직이지 않았다!

 

전이는 우선순위가 있기 때문에 앉을 줄(Crouch) 알았다.

하지만 실제로는 그냥 움직임이 멈추었다.상태 2개는 못받는 모양.

지인에게 물으니 고장나는 건 트리거를 실행못시켰기 때문이라고 한다.

트리거 대신 Bool을 써보니 잘된다!

 

강의대로 코드를 짰더니 조건을 삼중으로 체크하고 있었다. 그런데 전이자체가 조건을 거는거라 이렇게까지 할 필요가 있을까? 싶긴 하다. 

 

어쨌든 표준을 쓰고 싶지만... 걱정하는 문제들에 대한 해결책이 선명하지가 않다.

결국은 스스로 만들어써야 하겠다.