포스트

섹션6. Animation

위 글은 인프런에 있는 Rookiss님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진 강의를 듣고 남긴 필기입니다.

애니메이션 추가 및 블렌딩 적용

  • 캐릭터가 이동할 때와 가만히 서있을 때 재생할 애니메이션을 추가하고, 달리다가 멈출 때 자연스러운 전환을 위해 애니메이션 블렌딩을 적용.

Untitled

  • 달릴때 재생할 RUN 애니메이션과, 가만히 서있을 때 재생할 WAIT 애니메이션을 추가.
  • 그리고, 둘을 블렌딩하는 Blend Tree인 WAIT_RUN을 생성.

Untitled (1)

  • addMotion으로 WAIT00와 RUN00_F를 추가.
  • 해당 BlendTree에서 Blend 정도를 설정할 Parameter를 새로 만들어 Parameter로 설정해준다. wait_run_ratio
  • Motion들의 Threshold를 각각 0과 1로 설정.
    • Parameter가 0일때는 WAIT00 애니메이션만을 100% 재생하고, 1일때는 반대로 RUN00_F를 100% 재생, 만약 0.5라면 각각 50%씩 섞어서 재생하는 개념으로 이해하면 될듯?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// PlayerController 스크립트 내의 Update()안 다음의 코드들로 지금까지 설정한 Blend를 활용해 적절한 시점에 재생시킨다.

     if (_moveToDest)
      {
          wait_run_ratio = Mathf.Lerp(wait_run_ratio, 1, 10.0f * Time.deltaTime);
          Animator anim = GetComponent<Animator>();
          anim.SetFloat("wait_run_ratio", wait_run_ratio);
          anim.Play("WAIT_RUN");
      }
      else
      {            
          wait_run_ratio = Mathf.Lerp(wait_run_ratio, 0, 10.0f * Time.deltaTime);
          Animator anim = GetComponent<Animator>();
          anim.SetFloat("wait_run_ratio", wait_run_ratio);
          anim.Play("WAIT_RUN");
      }

StatePattern

  • switch문을 활용해서 상태에 따라 분기하는 방법
  • 현재 내 상태에 a적용할 수 있는 코드를 분리해서 만들 수 있다.
  • 애니메이션과의 관계를 직관적으로 인식할 수 있는 패턴

Pros 장점

  • 상태의 종류가 많아져도 관리가 쉽다.

Cons 단점

  • 동시에 둘 이상의 상태를 가질 수 없다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// State Pattern을 적용한 PlayerController
public class PlayerController : MonoBehaviour
{
	// ...

    public enum PlayerState
    {
        Die,
        Moving,
        Idle,
    }

    private PlayerState _state = PlayerState.Idle;

    void UpdateDie()
    {
        // 아무것도 못한다.
    }
    
    void UpdateMoving()
    {
        // ...
    }
    
    void UpdateIdle()
    {
	    // ...
    }
    
    private void Update()
    {
        switch (_state)
        {
            case PlayerState.Die:
                UpdateDie();
                break;
            case PlayerState.Moving:
                UpdateMoving();
                break;
            case PlayerState.Idle:
                UpdateIdle();
                break;
        }
    }

	// ...
}

Untitled (2)

위과 같이 상태 관리Tool로 하면, 훨씬 더 보기가 편하고 관리하기도 용이하다.

이렇게 만들기 위해서는 애니메이션 State를 잇는 Transition에 대해서 특정 파라미터에 대한 Transition 조건을 정한다.

(여기서는 speed 라는 변수를 만들고, 이 변수가 1보다 클때는 RUN, 작을때는 WAIT 애니메이션을 재생하도록 했다)

그리고 스크립트에서 다음과 같이 이 변수를 조정해주면 된다.

1
2
3
4
// 애니메이션
Animator anim = GetComponent<Animator>();
// 현재 게임 상태에 대한 정보를 넘겨주어, 애니메이션 전환을 툴 자체에 맡긴다.
anim.SetFloat("speed", _speed);

Animation Event

Keyframe Animation에서 사용할 수 있는 이벤트

Untitled (3)

  • 위와 같이 애니메이션의 한 frame에 특정 함수를 Call하는 이벤트를 삽입할 수 있는 기능.

Untitled (4)

  • 해당 게임 오브젝트에 부착되어 있는 스크립트의 함수를 지정할 수 있다.

Untitled (5)

1
2
3
4
5
6
7
public class PlayerController : MonoBehaviour
{
	void OnRunEvent(int a)
	{
		Debug.Log($"뚜벅 뚜벅{a}");
	}
}
  • 이렇게 외부에서 Import한 애니메이션에도 Animation Event를 지정해줄 수 있다.
  • 이 이벤트는 게임 오브젝트에 부착되어있는 스크립트의 함수가 받는다. (함수의 시그니쳐는 일치해야 한다. 이름, 매개변수)
  • float, int, String, Object를 매개변수로 함수에 넘겨줄 수 도 있다.

여러모로 유용해보인다. 캐릭터가 움직일 때 발자국 소리를 타이밍 맟게 출력시킨다던지 하는 방식으로 활용 가능해보인다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.