unity3d状态机基础学习(一)

网上也有很多关于状态机的教程,我不觉得我写的比别人好。但是自己写的总是便于自己理解

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

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方法里面添加判断就可以了。代码我就不贴了

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值