게임 개발/Unity

[Unity C#] FSM 디자인 패턴 적용시켜보기

Heesuk Lee 2019. 3. 3. 16:48

FSM in Unity


이전에 공부했었던 FSM, finite state machine을 유니티 상에서 구현해 캐릭터의 idle, move 상태를 구현했습니다.

이러한 디자인패턴을 기반으로 캐릭터들을 구현하게된다면 좀더 아름다운 코드가 나올수있을것같습니다.


완벽하게는 아니지만 각 객체의 역할을 분리할수있었다는 점에서 편리할수있을것같습니다.



우선 앞으로 정의할 상태들의 인터페이스 IState를 만들었습니다. 


public interface IState

{

// 인터페이스로 구현함으로써 player클래스에서 이 인터페이스로 호출합니다.

void OnEnter(Player player);

void Update();

void OnExit();

}



OnEnter는 상태가 시작될때 호출됩니다.  player클래스를 파라미터로 받아오면서 각 state클래스안에서 player에 접근시킬 수 있습니다.

(현재는 player의 색깔만을 변화시켜주지만 후에는 애니메이션, 프로퍼티등에 접근할수있을것같습니다.)


Update()는 상태가 유지되는동안 계속 호출해주는 함수입니다. 조건체크나 계속수행해줘야할것들을 구현합니다.


onExit()은 상태를 탈출하면서 호출됩니다. 초기화해줄것이나 제거할것들을 여기서 구현합니다.



EX) IdleState 구현


public class IdleState : IState {

private Player player;


void IState.OnEnter(Player player)

{

//player 프로퍼티 초기화

this.player = player;

// 초기화 구현

}


void IState.Update()

{

               // 실행할것 구현

if(이동키입력) 

{

// 다른상태로 이동

player.SetState(new MoveState());

}

}


void IState.OnExit()

{

//종료되면서 정리해야할것 구현

}


}



Player 클래스입니다.


public class Player : MonoBehavior {


private IState currentState;

private SpriteRenderer PlayerRenderer;

private Vector3 Direction;


private void Awake() 

{

//idleState를 시작해줍니다.

SetState(new IdleState());

}


private void Update() 

{

// state의 update를 호출하는 부분입니다. 

// 여기서는 꼭 update가 아닌 코루틴으로 리팩토링해도 좋을것같다는 생각을 했습니다.

currentState.Update();

}



public void SetState(IState nextState) 

{

// 다음 state로 이동구현


if(currentState != null) 

{

// 기존의 상태가 존재했다면 OnExit()호출

currentState.OnExit();

}


// 다음state 시작

currentState = nextState;

currentState.OnEnter(this);

}



// state에서 필요한 함수를 player에서 구현해 호출하는식으로 진행하면 될것 같습니다.

}



player에서 onAwake()에서 idle상태를 시작하며 그뒤로는 idle상태에서 조건을 검사해 다음상태로 이동하는식으로 구현하면 될것같습니다.



다음은 테스트영상입니다.


저는 상태의 변화를 색으로 체크해봤습니다.

초록색이 idle상태이며

파란색이 move상태입니다.









반응형