이 영역을 누르면 첫 페이지로 이동
나날이스튜디오 블로그 블로그의 첫 페이지로 이동

나날이스튜디오 블로그

페이지 맨 위로 올라가기

나날이스튜디오 블로그

나날이스튜디오의 일상, 아트/테크 노하우, 작품을 소개합니다.

SendMessage로 FSM 구현해보기 (Unity3D)

  • 2022.01.27 09:00
  • 개발/Design Pattern
글 작성자: 개발팀 한경진

# Introduce

FSM을 구현하기 위해 State Pattern을 다뤄보던 중,

SendMessage를 이용하여 기존 사용하던 FSM을 더 가독성 좋게 구현하게 되어서 공유하려 합니다.

 

 

FSM?

FSM 은 유한 상태 기계(Finite State Machine)를 의미합니다.

유한 상태 기계는 말 그대로 유한한 수의 상태를 가진 기계를 이야기 하는데요.

다음과 같은 특징을 지닙니다.

 

  • 유한 상태 기계는 유한한 수의 상태들을 가진다.
  • 그 중 반드시 하나의 상태만 취한다.
  • 현재 상태는 특정 조건이 되면 다른 상태로 변할 수 있다.
  • 유한 상태 기계는 가능한 상태들의 집합과 각 상태들의 전이 조건으로 정의될 수 있다.
  • 상태들을 그래프로 표현이 가능하다.

 

# Pros & Cons

장점

- 구현이 간단하다.

- 직관적이다.

- 원하는 함수들만 구현할 수 있다.

 

단점

- 규모가 커진다면 설계가 복잡해진다.

- 구조가 단순한 만큼 예측이 가능하다.

- SendMessage의 비용

 

장점은 매우 간단합니다. 

기본적인 FSM의 장점들을 모두 가져오며 추가로 원하는 항목의 함수들만 구현하면 되기 때문에 코드 가독성은 더 좋아지게 됩니다. 

 

단점으로는 기본적인 FSM의 단점들과 추가로 SendMessage의 비용이 부담되는데,

유니티의 SendMessage는 런타임 중 리플렉션을 통해 함수 호출하는 게 아니라 함수명을 String 형태로 Map으로 관리하기 때문에

일반적으로 아는 SendMessage만큼 느리진 않다고는 하지만

어찌되었든 직접 클래스 내에서 호출 하는 것 보다는 무거울 것이 확실하기 때문입니다.

 

# For example

#region FSM_Declare

// FSM 선언부
private bool _isNewState;                       // 상태가 변해야 하는지 알려주는 변수
private enum STATE { Idle, Chase, Flee }      // 상태들 선언. 해당 상태들은 상태명 뒤에 Enter,Update,Exit을 붙여 함수화됩니다.
private STATE _State = STATE.Idle;            // 현재 상태 변수

// 상태를 변경할 때 호출합니다.
private void SetState(STATE state)
{
	_isNewState = true;
	_State = state;
}

// FSM을 루프시키는 이터레이터입니다.
private IEnumerator FSM()
{
	while (true)
	{
		_isNewState = false;
		yield return StartCoroutine(FSM_State(_State));
	}
}

// 현재 상태의 함수를 호출해주는 이터레이터입니다. (ex. IdleEnter(), IdleUpdate(), IdleExit())
private IEnumerator FSM_State(STATE state)
{
	SendMessage(string.Format("{0}Enter", state), SendMessageOptions.DontRequireReceiver);

	do
	{
		yield return null;
		if (_isNewState)
		{
			SendMessage(string.Format("{0}Exit", state), SendMessageOptions.DontRequireReceiver);
			yield break;
		}

		SendMessage(string.Format("{0}Update", state), SendMessageOptions.DontRequireReceiver);

	} while (!_isNewState);

	SendMessage(string.Format("{0}Exit", state), SendMessageOptions.DontRequireReceiver);
}

#endregion

 

FSM에 꼭 필요한 변수와 함수들을 선언하는 구역입니다.

 

SetState() 함수를 통해 상태 변경을 할 수 있습니다.

상태가 변할때마다 FSM() 에서 FSM_State() 코루틴을 실행하게 되고,

FSM_State() 에서 현재 상태의 Enter, Update, Exit 함수를 SendMessage를 통해 호출합니다.

 

#region FSM_Implement
// FSM 구현부. 상태명 + Enter, Update, Exit 으로 구현합니다.
// 필요한 경우에만 구현하면 됩니다. 필요하지 않다면 함수조차 구현하지 않아도 무관합니다.
    
private void IdleEnter()
{
    Debug.Log("Idle Start");
}

private void IdleUpdate()
{
    Debug.Log("Idle Update");
}

private void IdleExit()
{
    Debug.Log("Idle Start");
}

#endregion

 

FSM의 상태를 구현하는 구역입니다.

 

SendMessage(DontRequireReceiver)를 통해 호출 하기 때문에 필요한 상태의 필요한 함수만 구현할 수 있습니다.

예를 들어, IdleUpdate() 함수는 필요하지만 IdleEnter(), IdleExit()이 필요하지 않다면 구현하지 않아도 괜찮습니다.

 

단, 위에서 선언한 열거형 STATE의 상태들과 동일한 이름을 사용해야 합니다.

 

# Epilogue

FSM을 코루틴과 SendMessage로 최대한 간단히 구현해 보았습니다.

간단한 AI나 상태 패턴을 구현할 때 도움이 되셨으면 좋겠습니다.

감사합니다.

 

# Refrences

https://ozt88.tistory.com/8

저작자표시 비영리 변경금지 (새창열림)

'개발 > Design Pattern' 카테고리의 다른 글

Command Pattern  (0) 2022.01.24
Singleton  (0) 2022.01.14

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • Command Pattern

    Command Pattern

    2022.01.24
  • Singleton

    Singleton

    2022.01.14
다른 글 더 둘러보기

정보

나날이스튜디오 블로그 블로그의 첫 페이지로 이동

나날이스튜디오 블로그

  • 나날이스튜디오 블로그의 첫 페이지로 이동

검색

메뉴

  • 🏠 홈
  • 🏷 태그
  • 📖 방명록

카테고리

  • 분류 전체보기 (14)
    • 나날이스튜디오 (7)
      • 팀 (1)
      • 일상 (6)
      • 작품 (0)
    • 개발 (7)
      • Design Pattern (3)
      • Github (0)
      • Unity3D (3)
    • 아트 (0)

최근 글

아카이브

정보

나날이스튜디오의 나날이스튜디오 블로그

나날이스튜디오 블로그

나날이스튜디오
    나날이스튜디오 블로그
    나날이스튜디오

    블로그 구독하기

    • 구독하기
    • RSS 피드

    방문자

    • 전체 방문자
    • 오늘
    • 어제

    티스토리

    • 티스토리 홈
    • 이 블로그 관리하기
    • 글쓰기
    Powered by Tistory / Kakao. © 나날이스튜디오. Designed by Fraccino.

    티스토리툴바