FSM 유한상태기계 공부 #1 [디자인패턴]

신지한·2023년 12월 26일
0

개발노트

목록 보기
3/15
post-thumbnail

📢 개발노트에 앞서서

본 개발노트는 혼자서 유니티 게임개발 독학하는 과정에서
유용하게 사용될만한 요소들을 구현 방법과 함께 기록&공유하는 게시글이며
부족한점이 있을 수 있어 참고해서 봐주시면 감사하겠습니다

❗ 본 게시글은 유튜브 고박사의 유니티 노트의 영상의 내용을 정리한 게시글로 모든 내용은 영상출처입니다!

❗ 게시글의 내용은 제가 참고하도록 작성한 글이니 자세한 내용은 영상을 직접 보시는걸 권장드립니다!


참고영상 >> https://youtu.be/O_NJaHpbjaI?si=kYIXKfsGVKE_30vH

📚 내용 정리

FSM이란?

  • 주어지는 모든 시간에서 처해 있을 수 있는 유한 개의 상태를 가지고
    주어지는 입력에 따라 어떤 상태에서 다른 상태로 전환시키거나
    출력이나 액션이 일어나게 하는 장치 또는 그런 장치를 나타낸 모델

  • 유한상태기계 바탕에 깔린 아이디어는 객체의 행동을 쉽게 처리할 수 있는
    덩어리 또는 상태들로 분해하는 것

    플레이어, 적, NPC와 같은 캐릭터의 행동을 "대기", "걷기", "근거리공격" 등과 같이
    쉽게 처리할 수 있는 상태 단위로 관리하는 것

FSM의 장점

  • 쉬운 구현
    • 행동 단위로 분할된 구조를 가지기 때문에 구조를 알아보기 쉽고, 구현이 쉽다
  • 오류수정 용이
    • 게임 에이전트(캐릭터)의 행동을 쉽게 관리할 수 있는 클래스 단위로 분할하기 때문에 에이전트의 동작이 이상하면 해당 동작의 클래스에서 오류를 발견할 수 있기 때문에 오류수정이 용이하다
  • 유연한 코드
    • 프로그래머는 게임 에이전트의 유한상태기계를 조정하고 미세조정을 통해 게임 디자이너가 요구하는 행동을 쉽게 만들어줄 수 있다. 또한 새로운 상태들과 규칙들을 추가함으로써 에이전트 행동의 범위를 간단하게 확장시킬 수도 있다
  • 직관적인 코드
    • 게임 에이전트의 행동을 여러 개의 상태들로 분해하고, 이 상태를 전환하는데 요구되는 규칙들을 나열하기 때문에 해당 에이전트가 가지고 있는 상태와 상태의 변화를 직관적으로 볼 수 있다. 상태 테이블, 다이어그램 등을 통해 비전공자인 사람들에게 에이전트의 상태를 쉽게 설명할 수 있고, 상태에 대해 논의할 수 있다

단계별 FSM

  • 1단계. if-then/ switch-case를 이용한 아주 단순한 FSM 구현
    • 단순 조건 비교(if-then / switch-case)를 이용한 상태 구현
    • 장점:
      • 구현하는 알고리즘이 단순하기 때문에 구현이 쉽다
    • 단점:
      • 어떤 상태로 들어갈 때와 나갈 때의 행동 정의가 어렵다(코드가 복잡해짐)
      • 상태의 개수가 늘어남에 따라 코드의 복잡도가 증가한다(수정이 어려움)
  • 2단계. 하나의 에이전트가 사용할 수 있는 FSM 구현
    • 에이전트와 상태의 분리, 내장된 규칙들을 적용
      • 클래스의 상속과 Up-Casting을 적용
        - 에이전트의 모든 상태들이 상속받는 기반 클래스 State Class 구현
        - 에이전트는 State Class 타입의 멤버 변수를 가지고 있으며, 해당 변수에 현재 상태를 저장하고, 업데이트하여 상태를 재생
    • 장점:
      • 상태의 개수가 늘어나도 해당 상태에 대해서만 정의하면 된다(상태가 외부에 있기 때문)
      • 상태로 들어갈 때와 나갈 때의 행동 정의가 가능하다(상태가 변경될 때 메소드 호출)
    • 단점:
      • 현재까지는 한 종류의 에이전트에 대해서만 사용 가능한 FSM 이기 때문에 다른 종류의 에이전트가 생기면 동일한 코드를 또 작성해야 하는 번거러움이 있다(코드의 재사용 X)
      • 코드를 이해하고 구현하는 것이 조금 어려워 졌다
  • 3단계. 여러 에이전트가 사용할 수 있는 FSM 구현
    • 재사용 가능한 State Class 구현(일반화 클래스 적용)
      • 2단계의 단점인 한 종류의 에이전트만 사용 가능한 FSM 보완
    • 상태를 관리하고 제어하는 StateMachine Class 구현
      • 상태에 관련된 내용은 에이전트들이 동일하게 사용하기 때문에 에이전트 외부에 클래스로 만들고, 에이전트가 참조 클래스로 활용하도록 함
    • 전역 상태와 상태 블립
      • 현재 상태와 관계없이 계속해서 업데이트되어야 하는 전역 상태
      • 바로 직전에 했던 상태를 기억하고, 그 상태로 돌아갈 수 있는 상태 블립
    • 장점:
      • 상태의 개수가 늘어나도 해당 상태에 대해서만 정의하면 된다(상태가 외부에 있기 때문)
      • 상태로 들어갈 때와 나갈 때의 행동 정의가 가능하다(상태가 변경될 때 메소드 호출)
      • 서로 다른 형태의 여러 에이전트가 사용할 때 상태 관련 코드 작성을 최소화 할 수 있다
    • 단점:
      코드를 이해하고 구현하는 것이 더 어려워 졌다
  • 4단계. 에이전트들 간의 소통을 위한 정보 전달 시스템
    • 전보 구조체 작성
      • 메시지 전달을 위한 메시지 구조체 작성(보낸 사람, 받는 사람, 시간, 내용 등)
    • 메시지 처리(송/수신)를 위한 에이전트 전화번호부 구현
      • 메시지를 보내거나 받는 에이전트에 대한 정보를 가지고 있는 EntitiyManager Class 구현
    • 메시지 전송 구현
      • 메시지를 전송하는 MessageDispatcher Class 구현
      • 바로 보내는 메시지 처리
      • 시간이 지연되어 보내지는 메시지 처리
    • 전송 받은 메시지를 처리
      • 메시지를 전달 받고, 읽어본 후 하게 될 행동 구현
        - StateMachine Class에 HandleMessage() 메소드 구현
        - 메시지를 처리하는 에이전트의 상태에 OnMessage() 메소드 구현

📌 공부 후기

현재 내가 1인개발로 개발하는 게임에서
몬스터들의 AI를 개별적으로 구현하기 위해서 효율적인 코드가 필요하다고 생각했고
디자인 패턴에 대해서 제대로 공부해야겠단 마음을 먹어서

우선 몬스터 AI를 구현하는데 가장 적합하다고 생각든 FSM 유한상태기계 부터 공부를 해보기로 하였다
고박사의 유니티 노트에서 설명해주는 내용 바탕으로 차근차근 공부하고
다양한 레퍼런스 참고해서 코드를 구현할 거 같다

이번 영상을 통해 공부한 내용에선 FSM 단계에 대한 설명이 많은데
다양한 몬스터에 적용하기 위해선 4단계는 아직 감이 잘 안잡혔고
3단계정도의 코드를 구현하는게 필요하다고 생각이 든다

관련해서 공부하는 내용을 계속해서 올릴거같다

profile
게임 개발자 지망생

0개의 댓글