유니티
상태(State) 패턴 with Unity
코다람쥐
2022. 2. 4. 22:03
1. 상태 패턴
상태 패턴은 객체에 상태를 정해서 상태에 맞는 로직을 수행하는 디자인 패턴이다.
사용하는 이유
if와 else로만 구현을 하게되면 스파게티 코드가 될 수 있기 때문에 객체의 상태로 분리시켜서 로직을 수행하면 이러한 문제를 해결할 수 있다.
enum과 swtich를 활용한 상태 패턴
우선 enum을 통해서 상태를 열거한다.
public enum PlayerState
{
Die,
Moving,
Idle,
}
업데이트문에서 switch문을 통해서 상태에따라 실행될 함수들을 집어넣는다.
PlayerState _state = PlayerState.Idle;
void Update()
{
switch(_state)
{
case PlayerState.Die:
UpdateDie();
break;
case PlayerState.Moving:
UpdateMoving();
break;
case PlayerState.Idle:
UpdateIdle();
break;
}
}
이런식으로 함수들을 정의하여 이제 상태가 변화하면 그에 맞는 로직을 처리하게끔 구현이 된다.
void UpdateMoving()
{
Vector3 dir = _destPos - transform.position; // 방향값 가져오기
if (dir.magnitude < 0.001f) // 도착완료하면 false로 설정
{
//_moveToDest = false;
_state = PlayerState.Idle;
}
else
{
// 이동한 좌표에서 부들거리는 현상 제거
float moveDist = Mathf.Clamp(_speed * Time.deltaTime, 0, dir.magnitude);
// 목적지 좌표에 도착할 때 까지 계속 이동시킴
transform.position += dir.normalized * moveDist;
// 부드럽게 회전
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(dir), 10 * Time.deltaTime);
}
// 애니메이션
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");
}
void UpdateIdle()
{
//애니메이션
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");
}
위의 코드는 Idle상태가 기본이었다가 이동명령이 발생하면 Moving상태로 변화하고 이동이 끝나면 다시 Idle상태로 되돌아가는 로직이다.
만약 새로운 기능을 추가하고 싶으면 enum과 switch문에만 상태를 추가하고 로직은 따로 구현만 하면 된다.