您的位置:首页 > 移动开发 > Unity3D

unity3d状态机基础学习(一)

2017-02-03 10:32 134 查看
网上也有很多关于状态机的教程,我不觉得我写的比别人好。但是自己写的总是便于自己理解

这篇文章相当于自己的笔记了。。理解此文前必须懂委托

1、首先理解状态,比如人物的待机、移动、攻击。。分别是三种状态;那么我们定义一个状态的基类

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class State
{
///
/// 状态名
///
public string name = "";
///
/// 构造
///
public State(string _name)
{
name = _name;
}
public State()
{

}

public delegate void TransitionEventHandler(State _from, State _to);
public delegate void OnActionHandler(State _curState);

///
/// 进入时的事件
///
public TransitionEventHandler onEnter;//System.Action
///
/// 退出时的事件
///
public TransitionEventHandler onExit;
///
/// 在状态机Update()时候调用的更新事件
///
public OnActionHandler onAction;

public virtual void Enter(State _from, State _to)
{
if (onEnter != null)
onEnter(_from, _to);
}

public virtual void Excute(State _curState)
{
if (onAction != null)
onAction(_curState);
}

public virtual void Exit(State _from, State _to)
{
if (onExit != null)
onExit(_from, _to);
}
}


2、再来理解下状态机,就是一个操作状态的机器,那么我们定义一个Machine类

using UnityEngine;
using System.Collections;

public class Machine
{
private State curState = null;
private State lastState = null;

/*Update*/
public void Update ()
{
if (curState != null)
curState.Excute(curState);
}

/*状态改变*/
public void ChangeState (State _newState)
{
if (_newState == null)
{
Debug.LogError ("can't find this state");
}
if (curState != null && _newState.name == curState.name)
Debug.LogError("can't change to the same state");

//触发退出状态调用Exit方法
curState.Exit(curState, _newState);
//保存上一个状态
lastState = curState;
//设置新状态为当前状态
curState = _newState;
//m_pCurrentState.Target = m_pOwner;
//进入当前状态调用Enter方法
curState.Enter(lastState, curState);
}

public Machine()
{
curState = null;
lastState = null;
}

public Machine(State _curState)
{
curState = _curState;
lastState = new State("init");
curState.Enter(lastState, _curState);
}
}


3、接着我们可以实例化几个状态,然后实例化一个状态机来操作这几个状态

using UnityEngine;
using System.Collections;

public class TestMachine : MonoBehaviour {

protected State moveState = null;
protected State idleState = null;
protected State attackState = null;

Machine curMachine = null;

void Start () {
idleState = new State("idle");
idleState.onEnter = EnterIdle;
idleState.onExit = ExitIdle;
idleState.onAction = ExcuteIdle;

moveState = new State("move");
moveState.onEnter = EnterMove;
moveState.onExit = ExitMove;
moveState.onAction = ExcuteMove;

attackState = new State("attack");
attackState.onEnter = EnterAttack;
attackState.onExit = ExitAttack;
attackState.onAction = ExcuteAttack;

curMachine = new Machine(idleState);
}

void Update () {
if (curMachine != null)
curMachine.Update();
}

void EnterIdle(State _from, State _to)
{
Debug.Log("EnterIdle _from:" + _from.name);
}
void ExitIdle(State _from, State _to)
{
Debug.Log("ExitIdle _to:" + _to.name);
}
void ExcuteIdle(State _curState)
{

}

void EnterMove(State _from, State _to)
{
Debug.Log("EnterMove _from:" + _from.name);
}
void ExitMove(State _from, State _to)
{
Debug.Log("ExitMove _to:" + _to.name);
}
void ExcuteMove(State _curState)
{

}

void EnterAttack(State _from, State _to)
{
Debug.Log("EnterAttack _from:" + _from.name);
}
void ExitAttack(State _from, State _to)
{
Debug.Log("ExitAttack _to:" + _to.name);
}
void ExcuteAttack(State _curState)
{

}

void OnGUI()
{
if (GUILayout.Button("idle"))
{
if (curMachine != null)
curMachine.ChangeState(idleState);
}
if (GUILayout.Button("move"))
{
if (curMachine != null)
curMachine.ChangeState(moveState);
}
if (GUILayout.Button("attack"))
{
if (curMachine != null)
curMachine.ChangeState(attackState);
}
}
}


4、接着可以多加一个骑马的状态(ride),那么此时我们需要考虑是否可以从攻击状态转换到骑马状态?骑马状态是否可以切换到攻击状态?

      只需要加一个能跳转的状态List,然后在ChangeState方法里面添加判断就可以了。代码我就不贴了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Unity3d 状态机