기타/미분류
유한상태기계
http://hyunity3d.tistory.com/575
using UnityEngine; using System.Collections; public class MonsterCtrl : MonoBehaviour { //몬스터의 상태정보 있는 eNUMERABLE 변수 선언 public enum MonsterState { idle, trace, attack, die}; public MonsterState monsterState = MonsterState.idle; //각종 컴포넌트 미리 저장 private Transform monsterTr; private Transform playerTr; private NavMeshAgent nvAgent; //추적 거리. public float traceDist = 10f; //공격 거리. public float attackDist = 2f; //몬스터 사망 여부 private bool isDie = false; // Use this for initialization void Start () { monsterTr = GetComponent<Transform>(); playerTr = GameObject.FindWithTag("Player").GetComponent<Transform>(); nvAgent = GetComponent<NavMeshAgent>(); //일정한 간격으로 몬스터의 행동상태를 체크 StartCoroutine(this.CheckMonsterState()); //몬스터의 상태에 따른 동작 StartCoroutine(this.MonsterAction()); } IEnumerator CheckMonsterState() { while(! isDie) { yield return new WaitForSeconds(0.2f); //몬스터와 플레이어 거리측정. float dist = Vector3.Distance(playerTr.position, monsterTr.position); if(dist <= attackDist) //공격 범위 이내에 들어왔는가? { monsterState = MonsterState.attack; } else if(dist <= traceDist) //추적 범위 이내에 들어왔는가? { monsterState = MonsterState.trace; } else { monsterState = MonsterState.idle; } } } IEnumerator MonsterAction() { while(! isDie) { switch(monsterState) { case MonsterState.idle: //추적중지. nvAgent.Stop(); break; case MonsterState.trace: nvAgent.destination = playerTr.position; break; case MonsterState.attack: break; } yield return null; } } // Update is called once per frame void Update () { } }
유니티를 사용할때 유한상태기계(FSM) 기법을 많이 사용한다. 유니티 자체에 제공하는 애니메이션 시스템도 유한상태기계를 사용하고 있어서 코딩을 할때도 이 기법을 사용하면 관리하기 편하다.
enum 으로 몬스터의 상태를 설정해주고 각 상태를 체크 해주며, 특정조건에 따라 상태를 변경 시켜준다. 여기선 코루틴을 사용하여 0.2초마다 몬스터의 상태를 체크해주어서 최적화를 시켜주었다.( 코루틴을 사용하지 않으면 매 프레임마다 체크를 하므로 성능이 저하될 우려가 있음.)
대강 흐름도는 이렇다.
void Start () { StartCoroutine(this.CheckMonsterState()); StartCoroutine(this.MonsterAction()); }
CheckMonstState 에서는 0.2초 간격으로 몬스터의 상태를 체크해준다.
- 플레이어와의 거리가 공격사정거리보다 가까우면 → 몬스터의 상태를 공격상태로 변경하고
- 플레이어와의 거리가 추적사정거리보다 가까우면 → 몬스터의 상태를 추적상태로 변경한다.
- 그것도 아니라면 몬스터의 상태를 idle 상태로 변경한다.
MonstAction 에서는 switch 에서 각각의 상태에 따라 추적을 중지하거나 추적을 시작한다.