Jtro的技术分享:unity中写FSM状态机

C#

浏览数:232

2019-8-30

HI :大家好
状态机,在游戏开发的时候,用的比较多,一般是用在开发游戏中小怪的逻辑上,最近比较忙,所以忘了简书种更新文章,
今天我给大家介绍2种状态机的写法。
这是去年写的机器人的状态机,我是做VR开发的,机器人在项目中起到提示玩家的作用,提示玩家,包含,确定将消息已经完整的提示到玩家,指引玩家到规定的位置,在玩家操作的地方等待玩家一共是3个状态.
这个机器人的运行模式已经被公司申请了专利,一种教学模式的指引机器人。当然状态机只是机器人的冰山一角。主要的功能就是机器人的状态机功能
第一种状态机:
首先是写一个接口:

//    脚本功能:状态机接口
//此脚本挂载在:  null  上
//    初创日期:2017.9.29
//        作者:张曙光
//  第一次修改:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public interface IState  {
     void Execute (AIController ac);
}

状态机的总控制:

//    脚本功能:机器人的有限状态机,用于传递状态机
//此脚本挂载在:   机器人根 上
//    初创日期:2017.9.29
//        作者:张曙光
//  第一次修改:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class FSM : MonoBehaviour {
    public IState currentState { get; private set;}
    public bool isCanMoveToCamera;
    public bool isCanMoveToMission;
    public bool isCanMoveToExcut;
    public AIController ac;
    // Use this for initialization
    void Start () {
        
    }//End of Start 

    public void ChangeState (IState newState)
    {
        currentState = newState;
    }
    // Update is called once per frame
    void Update () {
        if (currentState !=null &&ac !=null)
        {
            currentState.Execute (ac);
        }   
    }//End of Update
}

具体的状态,这里就举一个例子

//    脚本功能:
//此脚本挂载在:    上
//    初创日期:
//        作者:张曙光
//  第一次修改:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class _MoveCameraState : IState {
    public void Execute (AIController ac)
    {
        if (ac.fsm.isCanMoveToCamera) {
            ac.MoveToCamera ();
        } else {
            ac .fsm .ChangeState (new _MoveMissionState());
        }
    }
}

最后是一个控制器:

//    脚本功能:控制机器人做事
//此脚本挂载在:  机器人  上
//    初创日期:2017.9.29
//        作者:张曙光
//  第一次修改:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class AIController : MonoBehaviour {
    public FSM fsm;
    // Use this for initialization
    void Start () {
        fsm = GetComponent <FSM > ();
        fsm.ac = this;
        //初始化一个默认的状态机
        fsm .ChangeState (new _MoveCameraState ());
    }//End of Start 
    public void MoveToCamera ()
    {
        Debug.Log ("移动到相机");
    }
    public void MoveToMission ()
    {
        Debug.Log ("移动到任务点");
    }
    public void MoveToExcut()
    {
        Debug.Log ("移动到执行点");
    }
    public void test1 ()
    {
        Debug.Log ("test1");
    }
    public void test2 ()
    {
        Debug.Log ("test2");
    }
}

第一种状态机介绍完成,记得一点,状态机是环形切换,不能跳过状态
下面是第二种状态机:
有空再更新。。。。。

作者:Jtro