FSM in Unity3d

skyseer00@hotmail.com
FSM?
• Finite State Marchine(유한상태머신)
  – 유한개의 상태와 이런 상태들 간의 변환으로 구성된
    계산 모형.
  – 게임에서는 주로 몬스터AI 구현에 사용

• 유니티에서의 FSM
  – 코루틴(Coroutine) 을 사용
     • 스레드와 비슷한 결과를 만들지만 스레드와 달리 동시에
       하나만 수행하는 프로그래밍 기법(단일 스레드)
     • 부하가 걸리는 작업을 나눠서 시행하기 위해서도 사용
     • 코루틴은 루아(Lua)등 에서도 사용
     • StartCoroutine(시작), IEnumerator(리턴), yield return(양보)
       키워드 사용
Coroutine VS
• Coroutine VS 스레드
  – 둘다, 독립적인 동작 구현을 위해 사용
  – 코루틴은 자원공유 문제를 고민할 필요가 없다

• Coroutine VS Update
  – 둘다, 일정 주기마다 특정 작업을 반복하도록
    프로그램을 구성할 때 사용(콜백 함수)
  – 코루틴은 필요에 따라 호출을 제어(호출 시간, 호출
    중지)할 수 있으므로 CPU의 자원을 덜 소비
  – 코루틴은 가상화 함수가 아니기 때문에 오버헤드가
    없어서 Call부하는 없음… 실제 FPS에 영향은 없음.
Unity3d Coroutine 의 기본 구조
<ex_Coroutine.cs>
• StartCoRoutine(시작) StartCoroutine("FSM");
    void Start () {
         print ("A");
• IEnumerator(리턴)
         StartCoroutine("Example"); //StartCoroutine(Example(2.0f));
         print ("C");
• yield return(양보) 키워드 사용
    }

    IEnumerator Example(){             //IEnumerator Example(float waitTime){
        while(true){
             print ("B");
             yield return null;        //yield return new WaitForSeconds(waitTime);
        }
    }

  void Update () {
        print ("D");
  }
결과 : A B C D B D B D…..
결과 : A B C D D D…..D B D….. D B D…..
몬스터 AI 설계
• Init – 초기 몬스터 세팅            Spawn
                                                    StartCoroutine(“BattleFSM”)
                    StartCoroutine(IdleFSM(5.0f))
• Idle - 유휴                                                      Retreat
• Move – 이동                    Init
• Search – 플레이어 감지
                                                                  Chase
                                               Update ()
•   Chase – 추격 이동              Idle

•   Attack – 공격                                 Search
                                                                 Attack
•   Retreat - 후퇴              Move
•   Flee – 도망
                                                                  Flee
몬스터 AI 구현


<Monster.cs>

     private enum State {
           Init,             //make sure that everything we need is here
           Idle,             //do nothing
           Move,             //random moving
           //Setup,                 //assign the values to the things we need
           //Search,                //find the player
           Chase,            //move to player
           Attack,                  //attack the player
           Retreat,          //retreat to spawn point
           Flee              //run to the nearest spawn point with another mob
     }
몬스터 AI 구현
     void Start() {
            _state = MonsterObject.State.Init;
            StartCoroutine(IdleFSM(5.0f));

     }

     private IEnumerator IdleFSM(float waitTime) {
           while(_alive) {
//               Debug.Log("Alive: " + _alive);
                 switch(_state) {
                 case State.Init:
                        Init();
                        break;
                 case State.Idle:
                        Idle();
                        break;
                 case State.Move:
                        Move();
                        break;
                 }

                 yield return new WaitForSeconds(waitTime);
           }
     }
몬스터 AI 구현
     private IEnumerator BattleFSM() {
           while(_alive) {
//               Debug.Log("Alive: " + _alive);
                 switch(_state) {
                 case State.Chase:
                        Chase();
                        break;
                 case State.Attack:
                        Attack();
                        break;
                 case State.Retreat:
                        Retreat();
                        break;
                 case State.Flee:
                        Flee();
                        break;
                 }

                 yield return null;
           }
     }
몬스터 AI 구현

      void Update ()
      {

            Debug.DrawLine(_target.transform.position, _myTransform.position, Color.yellow);

            if(_balttle == false){
                   if(Vector3.Distance(_target.position, _myTransform.position) > maxCloseDistance &&
Vector3.Distance(_target.position, _myTransform.position) < findPlayerDistance){
                          Debug.Log("***Battle Start***");
                          _balttle = true;
                          StopCoroutine("IdleFSM");
                          StartCoroutine("BattleFSM");
                          _state = MonsterObject.State.Chase;
                   }
            }

      }
FSM의 활용
• 스스로 여러개의 상태를 갖고 스스로
  상태를 변화시키는 모든 객체에 활용 가능
 – Ex. MonsterGenerator, AnimateSprite컴포넌트
참고 사이트
•

120629 fsm in unity3d skyseer

  • 1.
  • 2.
    FSM? • Finite StateMarchine(유한상태머신) – 유한개의 상태와 이런 상태들 간의 변환으로 구성된 계산 모형. – 게임에서는 주로 몬스터AI 구현에 사용 • 유니티에서의 FSM – 코루틴(Coroutine) 을 사용 • 스레드와 비슷한 결과를 만들지만 스레드와 달리 동시에 하나만 수행하는 프로그래밍 기법(단일 스레드) • 부하가 걸리는 작업을 나눠서 시행하기 위해서도 사용 • 코루틴은 루아(Lua)등 에서도 사용 • StartCoroutine(시작), IEnumerator(리턴), yield return(양보) 키워드 사용
  • 3.
    Coroutine VS • CoroutineVS 스레드 – 둘다, 독립적인 동작 구현을 위해 사용 – 코루틴은 자원공유 문제를 고민할 필요가 없다 • Coroutine VS Update – 둘다, 일정 주기마다 특정 작업을 반복하도록 프로그램을 구성할 때 사용(콜백 함수) – 코루틴은 필요에 따라 호출을 제어(호출 시간, 호출 중지)할 수 있으므로 CPU의 자원을 덜 소비 – 코루틴은 가상화 함수가 아니기 때문에 오버헤드가 없어서 Call부하는 없음… 실제 FPS에 영향은 없음.
  • 4.
    Unity3d Coroutine 의기본 구조 <ex_Coroutine.cs> • StartCoRoutine(시작) StartCoroutine("FSM"); void Start () { print ("A"); • IEnumerator(리턴) StartCoroutine("Example"); //StartCoroutine(Example(2.0f)); print ("C"); • yield return(양보) 키워드 사용 } IEnumerator Example(){ //IEnumerator Example(float waitTime){ while(true){ print ("B"); yield return null; //yield return new WaitForSeconds(waitTime); } } void Update () { print ("D"); } 결과 : A B C D B D B D….. 결과 : A B C D D D…..D B D….. D B D…..
  • 5.
    몬스터 AI 설계 •Init – 초기 몬스터 세팅 Spawn StartCoroutine(“BattleFSM”) StartCoroutine(IdleFSM(5.0f)) • Idle - 유휴 Retreat • Move – 이동 Init • Search – 플레이어 감지 Chase Update () • Chase – 추격 이동 Idle • Attack – 공격 Search Attack • Retreat - 후퇴 Move • Flee – 도망 Flee
  • 6.
    몬스터 AI 구현 <Monster.cs> private enum State { Init, //make sure that everything we need is here Idle, //do nothing Move, //random moving //Setup, //assign the values to the things we need //Search, //find the player Chase, //move to player Attack, //attack the player Retreat, //retreat to spawn point Flee //run to the nearest spawn point with another mob }
  • 7.
    몬스터 AI 구현 void Start() { _state = MonsterObject.State.Init; StartCoroutine(IdleFSM(5.0f)); } private IEnumerator IdleFSM(float waitTime) { while(_alive) { // Debug.Log("Alive: " + _alive); switch(_state) { case State.Init: Init(); break; case State.Idle: Idle(); break; case State.Move: Move(); break; } yield return new WaitForSeconds(waitTime); } }
  • 8.
    몬스터 AI 구현 private IEnumerator BattleFSM() { while(_alive) { // Debug.Log("Alive: " + _alive); switch(_state) { case State.Chase: Chase(); break; case State.Attack: Attack(); break; case State.Retreat: Retreat(); break; case State.Flee: Flee(); break; } yield return null; } }
  • 9.
    몬스터 AI 구현 void Update () { Debug.DrawLine(_target.transform.position, _myTransform.position, Color.yellow); if(_balttle == false){ if(Vector3.Distance(_target.position, _myTransform.position) > maxCloseDistance && Vector3.Distance(_target.position, _myTransform.position) < findPlayerDistance){ Debug.Log("***Battle Start***"); _balttle = true; StopCoroutine("IdleFSM"); StartCoroutine("BattleFSM"); _state = MonsterObject.State.Chase; } } }
  • 10.
    FSM의 활용 • 스스로여러개의 상태를 갖고 스스로 상태를 변화시키는 모든 객체에 활용 가능 – Ex. MonsterGenerator, AnimateSprite컴포넌트
  • 11.