2015년 4월 15일 수요일

Finite State Machine for CSharp_Step2. 활용 예제

Explain.
게임 제작시 MainFrame(MainManager, GameManager 등)에서 FSM을 구현하는 방법 정리


MainFrame.cs
class MainFrame
{
    public enum State
    {
        Game,
        Lobby
    }

    FiniteStateMachine<MainFrame, State> FSM;
    
    LobbyState stateLobby = new LobbyState();
    GameState stateGame = new GameState();

    void Awake()
    {
        FSM = new FiniteStateMachine<MainFrame, State>(this);
        FSM.AddState(stateLobby);
        FSM.AddState(stateGame);

        FSM.ChangeState(stateLobby); // 시작시 stateLobby State
    }
}
LobbyState.cs
class LobbyState : FiniteState<MainFrame, MainFrame.State>
{
    public override void SetEntity(MainFrame entity)
    {
        base.SetEntity(entity);
    }
    public override void Enter()
    {
        base.Enter();
        //게임 입장시 이벤트 구현부
    }
    public override void Excute()
    {
        base.Excute();
        //게임 실행시 이벤트 구현부
    }
    public override void Exit()
    {
        base.Exit();
        //게임 퇴장시 이벤트 구현부
    }

    public override MainFrame.State _StateID
    {
        get
        {
            return MainFrame.State.Game;
        }
    }
}
GameState.cs
class GameState : FiniteState<MainFrame, MainFrame.State>
{
    public override void SetEntity(MainFrame entity)
    {
        base.SetEntity(entity);
    }
    public override void Enter()
    {
        base.Enter();
        //게임 입장시 이벤트 구현부
    }
    public override void Excute()
    {
        base.Excute();
        //게임 실행시 이벤트 구현부
    }
    public override void Exit()
    {
        base.Exit();
        //게임 퇴장시 이벤트 구현부
    }

    public override MainFrame.State _StateID
    {
        get
        {
            return MainFrame.State.Game;
        }
    }
}

Finite State Machine for CSharp_Step1. FSM 구현

Explain. 
유한 상태 기계라고 하며, 특정한 Input(event) 에 따라 해당하는 state(output)으로 변화하는 방법론. 다양한 분야(특히 게임)에 사용되어 지고있으며 상태에 변화에 따른 이벤트를 발생시킬수있으므로 좀더 유연한 로직을 구성할수있다. 이전에 게임 제작시 사용했던 현재도 사용하고있는 FSM에 대해 정리. 스크립트 설명의경우 주석으로 진행.

Step. 
1. FiniteStateMachine 구현
2. 간단한 사용법

FSM 구현

Summary.
 IState ( FiniteState의 명세를 담은 Interface )
 FiniteState ( State 클래스 )
 FiniteStateMachine ( FSM 클래스 )

IState.cs

interface IState<T>
{
    
    void Enter();
    void Excute();
    void Exit();

    T _StateID
    {
        get;
    }
}

FiniteState.cs
class FiniteState<T, U> : IState<U>
{
    protected T entity;

    public virtual void SetEntity(T entity)
    {
        this.entity = entity;
    }

    public virtual void Enter()
    {
        Console.WriteLine(typeof(T).ToString() + "Enter");
    }

    public virtual void Excute()
    {
        Console.WriteLine(typeof(T).ToString() + "Excute");
    }

    public virtual void Exit()
    {
        Console.WriteLine(typeof(T).ToString() + "Exite");
    }

    public virtual U _StateID
    {
        get
        {
            throw new ArgumentException("Exception");
        }
    }

}

FiniteStateMachine.cs
class FiniteStateMachine<T, U>
{
    private T entity; // State의 주체가 되는 class

    private Dictionary<U, FiniteState<T, U>> stateDic; // 전체 State

    private FiniteState<T, U> currentState; // 현재 상태
    private FiniteState<T, U> previousState; // 이전 상태

    /// <summary>
    /// 생성자
    /// </summary>
    /// <param name="entity">주체 class</param>
    public FiniteStateMachine(T entity)
    {
        this.entity = entity;
        stateDic = new Dictionary<U, FiniteState<T, U>>();
    }

    public void ExcuteState()
    {
        if (currentState != null) currentState.Excute();
    }

    public void ChangeState(FiniteState<T, U> nextState)
    {
        if (currentState == nextState) return;

        if(currentState != null)
        {
            currentState.Exit();
            previousState = currentState;
        }

        currentState = nextState;

        currentState.Enter();
    }

    public void ChangeState(U stateID)
    {
        try
        {
            FiniteState<T, U> state = stateDic[stateID];
            ChangeState(state);
        }
        catch(KeyNotFoundException)
        {
            // exception 처리
        }
    }

    //이전 state로 상태 되돌리기
    public void RevertState()
    {
        if (previousState != null)
            ChangeState(previousState);
    }

    public void AddState(FiniteState<T, U> state)
    {
        if (state == null) return;
        state.SetEntity(entity);
        stateDic.Add(state._StateID, state);
    }

    public void RemoveState(FiniteState<T, U> state)
    {
        stateDic.Remove(state._StateID);
    }
}

2015년 4월 8일 수요일

Visual Stduio2013에 Boost Library 설치하기.



Summary.
 - Boost Library란? C++ STL에 포함되기전 철저한 리뷰를 거쳐 실험적인 라이브러리. 매우 광대한 영역을 품고있으며 실제로 C++ STL 표준에 많은 부분이 포함되어지기도한다.
때문에, C++ 표준에 영향을 미치기도 한다.

Environment.
 - Visual Studio 2013 Ultimate.
 - Window 7 professional 64bit.

Step.
 - 1. boost Library 다운로드 , 압축해제
 - 2. Boost Lib 빌드
 - 3. VS2013 property에 lib 추가.


How to used?.
1. boost Library 다운로드 , 압축해제
  boost 홈페이지에 접속하여 boost lib 압축파일을 다운로드 한뒤
아무곳에나 압축해제하여 위치시킨다.

2.Boost Lib 빌드

  • 압축 해제된 폴더내의 bootstrap.bat 배치파일을 실행한다.
  • 그후 cmd를 실행한뒤 해당 폴더로 이동하고 b2파일을 실행하여 컴파일 한다.
    • b2 toolset=msvc-12.0 --build-type=complete --abbreviate-paths architecture=x86 address-model=32 install -j4
      • b2 : build boost
      • msvs-12.0 : vs version
      • j4 : 4 cores for parallel compilation 사용
  • 이후 20~30분 정도의 빌드 시간을 거친 뒤 header 파일 및 lib 파일이 생성 된다.
    • 경로 : C:\Boost
3. VS2013 property에 lib 추가.

Project Properties 창을 선택한뒤.

Include Directories 에 C:\Boost\include 폴더를 포함시킨다.




Reference.
 - How to use boost in visual studio

More.
 - 이후 boost 헤더파일을 포함시키면서 코딩을 진행하면 된다. 다만 link 단계에서의 종속성이 요구되는 부분을 사용할경우 따로 설정해야하는 부분이 있으니 기억해두고 진행한다.(레퍼런스 참고)