요약: 이 페이지에서는 Feel에 포함된 유한 상태 기계를 사용하는 방법을 설명합니다.
테이블 내용
|
상태 기계(State Machine)란?
상태 기계(또는 유한 상태 기계)는 계산의 수학적 모델입니다. 이는 주어진 시간에 정확히 하나의 유한한 상태 중 하나에 있을 수 있는 추상적인 기계입니다. 이는 게임에서 캐릭터의 상태, 무기의 상태, 캐릭터의 진행 상황 등을 추적하는 데 자주 사용되는 디자인 패턴입니다.
Feel에는 상태 기계를 처리하고, 상태를 저장하며, 이러한 변경에 대해 이벤트를 트리거하는 간단한 클래스인 MMStateMachine이 포함되어 있습니다. 필요하다면 이를 사용할 수 있습니다.
상태 기계 생성
아래 클래스는 상태 기계의 일반적인 사용 사례를 보여줍니다. 이 클래스는 입력을 읽고 "점프" 또는 "대시"를 수행하는 캐릭터 컨트롤러를 시뮬레이션합니다. 이를 테스트하려면, 새 빈 씬을 생성하고, 새 빈 게임 오브젝트를 생성한 후, 이름을 "MyTestCharacter"로 설정하고 MyCharacter 컴포넌트를 추가합니다. 재생 버튼을 누르면 화면에 디버그 콘솔이 현재 "캐릭터"의 상태를 표시합니다. 스페이스바, D 또는 R을 누르면 새로운 상태로 변경됩니다.
using MoreMountains.Tools;
using UnityEngine;
/// 매우 기본적인 캐릭터 컨트롤러의 데모 클래스입니다. 입력을 읽고 상태 기계를 업데이트합니다.
public class MyCharacter : MonoBehaviour
{
/// 유한 상태 기계의 모든 가능한 상태를 선언합니다.
public enum MovementStates { Null, Idle, Walking, Running, Dashing, Jumping }
/// 상태 기계를 선언하고, MovementStates에서 작동하도록 지정합니다.
public MMStateMachine<MovementStates> MovementState;
/// Awake에서 상태 기계를 초기화합니다.
private void Awake()
{
MovementState = new MMStateMachine<MovementStates>(this.gameObject, true);
}
/// Update에서 입력을 확인하고 캐릭터 컨트롤러의 메서드를 적절히 트리거합니다.
/// 이 메서드 각각은 상태 기계에서 캐릭터의 현재 상태를 변경합니다.
/// 실제 컨트롤러에서는 힘을 가하거나, 캐릭터를 이동시키거나, 속도를 변경하는 등의 작업을 수행합니다.
private void Update()
{
if (Input.GetKeyDown("space"))
{
Jump();
}
if (Input.GetKeyDown("d"))
{
Dash();
}
if (Input.GetKeyDown("r"))
{
Run();
}
// 현재 상태를 화면의 디버그 콘솔에 출력합니다.
MMDebug.DebugOnScreen("Current Character State", MovementState.CurrentState);
}
private void Jump()
{
MovementState.ChangeState(MovementStates.Jumping);
}
private void Dash()
{
MovementState.ChangeState(MovementStates.Dashing);
}
private void Run()
{
MovementState.ChangeState(MovementStates.Running);
}
}
상태 변경 감지
어떤 클래스에서든 이 시스템을 사용하여 상태 변화를 감지하고 이에 따라 행동할 수 있습니다. 이렇게 하면 "점프 상태를 종료할 때" 또는 "대시 상태에 진입할 때" 작업을 수행하는 것이 매우 쉬워집니다. 다음 클래스는 이러한 작업이 어떻게 수행되는지를 보여줍니다. 이를 테스트하려면, 이전 씬에서 동일한 객체 또는 씬의 다른 객체에 MyListeningClass 컴포넌트를 추가하세요.
using MoreMountains.Tools;
using UnityEngine;
/// 캐릭터가 상태를 변경할 때 동작하는 리스닝 클래스의 예제입니다.
public class MyListeningClass : MonoBehaviour, MMEventListener<MMStateChangeEvent<MyCharacter.MovementStates>>
{
// 활성화될 때 이벤트 변경 사항을 수신 대기합니다.
private void OnEnable()
{
this.MMEventStartListening<MMStateChangeEvent<MyCharacter.MovementStates>>();
}
// 비활성화될 때 이벤트 변경 사항 수신을 중지합니다.
private void OnDisable()
{
this.MMEventStopListening<MMStateChangeEvent<MyCharacter.MovementStates>>();
}
// 새로운 상태 변경 이벤트를 수신하면, 원하는 로직을 실행할 수 있습니다.
public void OnMMEvent(MMStateChangeEvent<MyCharacter.MovementStates> movementStateEvent)
{
// 상태 기계가 현재 있는 새로운 상태에 따라 작업을 수행할 수 있습니다.
switch (movementStateEvent.NewState)
{
case MyCharacter.MovementStates.Jumping:
Debug.Log("we're jumping now");
break;
case MyCharacter.MovementStates.Dashing:
Debug.Log("we're dashing now");
break;
}
// 이전 상태에 따라 작업을 수행할 수도 있습니다.
switch (movementStateEvent.PreviousState)
{
case MyCharacter.MovementStates.Running:
// 이벤트를 트리거한 게임 오브젝트에 대한 참조를 항상 얻을 수 있습니다.
Debug.Log("object " + movementStateEvent.Target + " was running but we're not running anymore");
break;
}
}
}
'유니티 에셋 > Feel' 카테고리의 다른 글
MMFloatingText (2) | 2024.07.14 |
---|---|
MMSceneLoading (0) | 2024.07.14 |
MMProgressBar (1) | 2024.07.14 |
MMRadio (1) | 2024.07.14 |
MMSequencer (2) | 2024.07.14 |