본문 바로가기
C#

delegate 를 기반으로 한 상태 기계 구현해보기

by Oz Driver 2025. 3. 12.

C#에서 상태 기계를 구현할 때, if-else 또는 switch-case 문을 사용하는 방식보다 델리게이트(delegate)를 활용하면 코드의 가독성과 유지보수성이 훨씬 좋아집니다.

이 글에서는 델리게이트를 활용한 상태 기계 구현 방법을 설명하고, 자기 클래스 내부에서 직접 상태를 변경하는 구조를 적용하는 방법을 소개하겠습니다.

 

 

상태 기계 (State Machine) 란?

상태 기계는 프로그램이 특정 상태 (State) 를 가지며, 조건에 따라 다른 상태로 전환되는 구조를 의미합니다. 게임 개발에서 자주 사용되며, 플레이어의 행동, UI 상태, AI 동작 등을 관리하는 데 유용합니다.

 

상태 기계를 사용하는 이유

* if-else 또는 switch-case 문을 줄여 코드의 가독성을 높일 수 있습니다.

* 상태를 독립적으로 관리할 수 있어 유지보수가 용이합니다

* 새로운 상태를 추가할 때 기존 코드를 수정하지 않아도 되어 확장성이 뛰어납니다.

 

델리게이트를 활용한 상태 기계의 기본 개념

델리게이트를 활용하면 switch-case 없이 상태를 쉽게 전환할 수 있습니다. 상태를 Action 델리게이트로 관리하면, 현재 상태에서 수행할 동작을 간결하게 구현할 수 있습니다.

public class StateMachine
{
    private Action currentState;

    public void SetState(Action newState)
    {
        currentState = newState;
        currentState?.Invoke(); // 상태 변경 즉시 실행
    }

    private void Update()
    {
        currentState?.Invoke(); // 매 프레임 현재 상태 실행
    }
}

 

방식 구현

아래 코드는 퀘스트 시스템을 예제로 삼아, 자기 클래스 내부에서 상태를 변경하는 델리게이트 기반 상태 기계를 구현한 것입니다.

using System;
using UnityEngine;

public class QuestManager : MonoBehaviour
{
    private Action questState;

    private void Start()
    {
        SetQuestState(NotStartedState); // 처음 상태 설정
    }

    private void Update()
    {
        questState?.Invoke(); // 현재 상태 실행
    }

    private void SetQuestState(Action newState)
    {
        questState = newState;
        questState?.Invoke(); // 상태 변경 즉시 실행
    }

    private void NotStartedState()
    {
        Debug.Log("퀘스트 시작 전");
        if (Input.GetKeyDown(KeyCode.Space))
        {
            SetQuestState(InProgressState);
        }
    }

    private void InProgressState()
    {
        Debug.Log("퀘스트 진행 중");
        if (Input.GetKeyDown(KeyCode.Return))
        {
            SetQuestState(CompletedState);
        }
    }

    private void CompletedState()
    {
        Debug.Log("퀘스트 완료");
    }
}

 

코드 분석

SetQuestState (Action newState)

* 새로운 상태를 Action으로 전달받아 questState 변수에 저장합니다.

* 저장된 상태를 즉시 실행하여 변경 사항을 바로 적용합니다.

 

Update()에서 questState?.Invoke();

* 현재 상태가 존재하면 매 프레임마다 해당 상태의 동작을 실행합니다.

* ?. 연산자를 사용하여 null 체크를 수행합니다.

 

상태 함수에서 직접 상태 전환

* 각 상태 함수에서 특정 조건이 충족되면 SetQuestState()를 호출하여 다음 상태로 변경합니다.

 

 

델리게이트 기반 상태 기계의 장점

* if-else 또는 switch-case를 사용하지 않아 코드가 깔끔해집니다.

* 상태 변경이 즉시 반영되어 다음 프레임을 기다리지 않고 바로 실행 가능합니다.

* 새로운 상태 추가 시 기존 코드 변경 없이 쉽게 확장 가능합니다. 

 

 

정리

델리게이트를 활용한 상태 기계는 가독성이 뛰어나고 유지보수가 용이한 구조를 제공합니다. 특히 자기 클래스 내부에서 상태를 변경하는 방식을 적용하면 더욱 직관적으로 상태를 관리할 수 있습니다.

게임 개발에서 플레이어 상태, AI 동작, UI 상태 관리 등에 유용하게 활용할 수 있으니, 프로젝트에 맞게 적용해보시기 바랍니다.