유한상태머신
애니메이션을 재생시키고 서로 상태를 변환시키기 위해서는 FSM(Finite State Machine)을 알아야 한다.
오늘 만들어볼 두더지의 상태 흐름은 아래와 같이 구성하기로 하였다.
각 상태의 변화에는 특정한 조건이 필요하다.
함수는 총 5개의 상태 * 2를 만들 것이다. 하나는 도입부, 그리고 하나는 상태에 따른 액션을 행동하는 함수.
아래 보면, 이 부분이 5개의 상태를 말한다.
이제 각각 상태를 변환 시킬 수 있는 조건들을 설정하면 된다.
public enum MoleState
{
None, Open, Idle, Close, Catch
}
우선 이 부분은 스크립트의 실행을 담당하는 부분인데 MS라는 변수값이 MoleState.Open이면 계속해서 Open_Ing()실행 시키도록 하고 있다.
과연 저기 MoleState.Open을 조절하는 부분이 어디일까 살펴 보자.
// Update is called once per frame
void Update () {
{
if (MS == MoleState.Open) {
Open_Ing ();
}
}
이 부분은 Open 이라는 상태를 구현한 부분이다.
일단 Open_On()에서는 애니메이션 재생을 담당한다. MoleState.Open이라는 상태로 선언하도록 만들었다. 그러고 나서 Ani_count를 0으로 세팅한다.
//Open
public void Open_On()
{
MS = MoleState.Open;
Ani_count = 0;
}
public void Open_Ing()
{
renderer.material.mainTexture = Open_Images [Ani_count];
Ani_count+=1;
if (Ani_count >= Open_Images.Length)
{
Idle_On();
}
}
사실 여기까지가 핵심적인 부분인 것 같다. 그 외의 부분들은 주기적으로 None 상태일 때 다른 함수로 보내는 설정이나, 애니메이션의 스피드 조절하는 부분이 전부이다.
가장 기본적으로 2D 애니메이션 출력을 할 수 있는 방법이다.
그 외에 각종 조건에 의해서 STATE를 변환 시키는 것은 또 다른 문제이다.
그럼 왜 On과 Ing 함수를 하나로 합치지 않았을까 생각해 봤는데, 의외로 단순했다.
Ani_count를 계속해서 0으로 세팅하면 문제가 생기니까 그런 것이다.
using UnityEngine;
using System.Collections;
public enum MoleState
{
None, Open, Idle, Close, Catch
}
public class Hole : MonoBehaviour {
public IEnumerator Wait(){
MS = MoleState.None;
Ani_count=0;
float wait_Time = Random.Range(1.5f, 1.5f);
yield return new WaitForSeconds(wait_Time);
Open_On();
}
public MoleState MS;
public Texture[]Open_Images;
public Texture[]Idle_Images;
public Texture[]Close_Images;
public Texture[]Catch_Images;
public float Ani_Speed;
public float _now_ani_time;
int Ani_count;
//Open
public void Open_On()
{
MS = MoleState.Open;
Ani_count = 0;
}
public void Open_Ing()
{
renderer.material.mainTexture = Open_Images [Ani_count];
Ani_count+=1;
if (Ani_count >= Open_Images.Length)
{
Idle_On();
}
}
//Idle
public void Idle_On()
{
MS = MoleState.Idle;
Ani_count = 0;
}
public void Idle_Ing()
{
renderer.material.mainTexture = Idle_Images [Ani_count];
Ani_count+=1;
if (Ani_count >= Idle_Images.Length)
{
Close_On();
}
}
//Close
public void Close_On()
{
MS = MoleState.Close;
Ani_count = 0;
}
public void Close_Ing()
{
renderer.material.mainTexture = Close_Images [Ani_count];
Ani_count+=1;
if (Ani_count >= Close_Images.Length)
{
StartCoroutine("Wait");
}
}
//Catch
public void Catch_On()
{
MS = MoleState.Catch;
Ani_count = 0;
}
public void Catch_Ing()
{
renderer.material.mainTexture = Catch_Images [Ani_count];
Ani_count+=1;
if (Ani_count >= Catch_Images.Length)
{
StartCoroutine("Wait");
}
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if(_now_ani_time>=Ani_Speed)
{
if (MS == MoleState.Open) {
Open_Ing ();
}
if (MS == MoleState.Idle) {
Idle_Ing ();
}
if (MS == MoleState.Close) {
Close_Ing ();
}
if (MS == MoleState.Catch) {
Catch_Ing ();
}
_now_ani_time = 0;
}
else
{
_now_ani_time += Time.deltaTime;
}
}
}
'게임개발자 > Unity3D' 카테고리의 다른 글
효과음 넣기와 두더지 종류 나누기 - 유니티로 만드는 인디게임. 두더지 잡기 게임 MollyMolly 함께 만들기(3) (0) | 2014.07.29 |
---|---|
기획서 작성 및 플로우 만들기 - 유니티로 만드는 인디게임. 두더지 잡기 게임 MollyMolly 함께 만들기(1) (0) | 2014.07.24 |
유니티로 만드는 인디게임. PushMan 프로토 타입 함께 만들기(3) (0) | 2014.07.23 |
유니티로 만드는 인디게임. PushMan 프로토 타입 함께 만들기(2) (0) | 2014.07.23 |
유니티로 만드는 인디게임. PushMan 프로토 타입 함께 만들기(1) (0) | 2014.07.23 |