Skip to content
/ TFSM Public

TFSM은 Unity와 C#에서 사용 가능한 일반적인 상태 기계입니다

Notifications You must be signed in to change notification settings

tigu77/TFSM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Unity와 C#에서 사용 가능한 일반적인 상태 기계

using System;
using System.Collections;
using UnityEngine;

namespace TFSM.Example
{
    //상태는 박싱을 막기 위해 IEquatable<T>를 구현해야 한다
    public struct SomeState : IEquatable<SomeState>
    {
        public enum Type
        {
            SomeState1,
            SomeState2,
            SomeState3
        }

        private Type type;
        

        public readonly bool Equals(SomeState other)
        {
            return type == other.type;
        }

        public static implicit operator SomeState(Type type)
        {
            return new SomeState
            {
                type = type
            };
        }
    }


    //예제 상태구현 베이스 클래스
    public abstract class SomeStateBase : BaseState<SomeState, StateMachineExample>
    {
        private Coroutine _coroutine;

        //머신에서 호출
        public override void OnEnter()
        {
            Debug.Log($"{GetType()} OnEnter");
            _coroutine = Context.StartCoroutine(OnUpdate());
        }

        //머신에서 호출
        public override void OnExit()
        {
            Debug.Log($"{GetType()} OnExit");

            if (_coroutine != null)
            {
                Context.StopCoroutine(_coroutine);
                _coroutine = null;
            }
        }

        //내부에서 호출
        protected virtual IEnumerator OnUpdate()
        {
            yield break;
        }

        //외부에서 호출
        public virtual void UpdateExternal()
        {
        }
    }

    public class SomeState1 : SomeStateBase
    {
        protected override IEnumerator OnUpdate()
        {
            yield return new WaitForSeconds(1f);

            StateMachine.ChangeState(SomeState.Type.SomeState2);
        }
    }

    public class SomeState2 : SomeStateBase
    {
        protected override IEnumerator OnUpdate()
        {
            yield return new WaitForSeconds(1f);

            StateMachine.ChangeState(SomeState.Type.SomeState3);
        }
    }

    public class SomeState3 : SomeStateBase
    {
        private float _endTime;
        public override void OnEnter()
        {
            base.OnEnter();
            _endTime = Time.time + 1f;
        }

        public override void UpdateExternal()
        {
            if(Time.time >= _endTime)
            {                
                StateMachine.ChangeState(UnityEngine.Random.Range(0, 2) == 0 ? SomeState.Type.SomeState1 : SomeState.Type.SomeState2);
            }            
        }
    }


    public class StateMachineExample : MonoBehaviour
    {        
        private StateMachine<SomeState, SomeStateBase, StateMachineExample> _stateMachine;

        private void Awake()
        {            
            _stateMachine = new StateMachine<SomeState, SomeStateBase, StateMachineExample>(this);
            _stateMachine.AddState<SomeState1>(SomeState.Type.SomeState1);
            _stateMachine.AddState<SomeState2>(SomeState.Type.SomeState2);
            _stateMachine.AddState<SomeState3>(SomeState.Type.SomeState3);

            //상태 변경에 대한 예외 처리가 필요한 부분은 콜백으로 구현
            _stateMachine.TryChangeState = (current, next) =>
            {
                return true;
            };
        }

        private void Start()
        {
            _stateMachine.StartState(SomeState.Type.SomeState1);
        }

        private void Update()
        {
            //현재 상태의 구현체에서 바로 호출
            _stateMachine.CurrentImplement.UpdateExternal();
        }
    }
}

About

TFSM은 Unity와 C#에서 사용 가능한 일반적인 상태 기계입니다

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages