섹션6. Animation
위 글은 인프런에 있는 Rookiss님의 [C#과 유니티로 만드는 MMORPG 게임 개발 시리즈] Part3: 유니티 엔진 강의를 듣고 남긴 필기입니다.
애니메이션 추가 및 블렌딩 적용
- 캐릭터가 이동할 때와 가만히 서있을 때 재생할 애니메이션을 추가하고, 달리다가 멈출 때 자연스러운 전환을 위해 애니메이션 블렌딩을 적용.
- 달릴때 재생할 RUN 애니메이션과, 가만히 서있을 때 재생할 WAIT 애니메이션을 추가.
- 그리고, 둘을 블렌딩하는 Blend Tree인 WAIT_RUN을 생성.
- 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;
}
}
// ...
}
위과 같이 상태 관리를 Tool로 하면, 훨씬 더 보기가 편하고 관리하기도 용이하다.
이렇게 만들기 위해서는 애니메이션 State를 잇는 Transition에 대해서 특정 파라미터에 대한 Transition 조건을 정한다.
(여기서는 speed 라는 변수를 만들고, 이 변수가 1보다 클때는 RUN, 작을때는 WAIT 애니메이션을 재생하도록 했다)
그리고 스크립트에서 다음과 같이 이 변수를 조정해주면 된다.
1
2
3
4
// 애니메이션
Animator anim = GetComponent<Animator>();
// 현재 게임 상태에 대한 정보를 넘겨주어, 애니메이션 전환을 툴 자체에 맡긴다.
anim.SetFloat("speed", _speed);
Animation Event
Keyframe Animation에서 사용할 수 있는 이벤트
- 위와 같이 애니메이션의 한 frame에 특정 함수를 Call하는 이벤트를 삽입할 수 있는 기능.
- 해당 게임 오브젝트에 부착되어 있는 스크립트의 함수를 지정할 수 있다.
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 라이센스를 따릅니다.