Unity3D数学基础(5)_ 简单的FSM

来源:互联网 发布:king域名永久 编辑:程序博客网 时间:2024/06/05 20:34

简单的FSM

(还有一个复杂的FSM,就是将每种状态都独立成类)


1.FSM功能分析

我家的猫的日常:


可以发现,这几件事情显然是有关联的,那么可以这样,逻辑就清晰多了。



2.FSM定义

百度百科一下

https://baike.baidu.com/item/%E7%8A%B6%E6%80%81%E6%9C%BA/6548513?fr=aladdin


3.一个简单的FSM例子


效果图:



主要实现代码:

FSM类

using UnityEngine;using System.Collections.Generic;public class FSM : MonoBehaviour {    protected Vector3 desPos;       /*当前目标点*/    protected GameObject[] posList;   /*巡逻点*/    protected virtual void Initialize() { }     /*初始化函数*/    protected virtual void FSMUpdate() { }      /*FSM*/    private void Start()    {        Initialize();    }    private void Update()    {        FSMUpdate();    }}

SimpleFsm类(要绑在emeny预设上面)

using UnityEngine;public class SimpleFSM : FSM {    /*敌人状态*/    public enum FSMState    {        None,        Patrol,     /*巡逻*/        Chase,      /*追逐*/        Attack,     /*攻击*/        Dead        /*死亡*/    }    #region 变量定义    private FSMState curState;               /*当前状态*/    private float curSpeed = 20f;            /*当前移动速度*/    private Transform player;               /*玩家位置*/    private GameObject buttle;              /*子弹*/    private float timer = 0;                    /*发射子弹计时器*/    #endregion    /*初始化*/    protected override void Initialize()    {        base.Initialize();        player = transform.parent.FindChild("Player(Clone)");      /*寻找玩家*/        curState = FSMState.Patrol;     /*初始化为巡逻状态*/        posList = GameObject.FindGameObjectsWithTag("point");   /*寻找所有巡逻点*/        buttle = Resources.Load<GameObject>("Perfabs/Current"); /*获得子弹*/        FindNextPoint();    }    /*FSM*/    protected override void FSMUpdate()    {        base.FSMUpdate();        /*进行状态选择*/        switch (curState)        {            case FSMState.Patrol:       /*巡逻*/                PatrolUpdate();                break;            case FSMState.Chase:        /*追逐*/                ChaseUpdate();                break;            case FSMState.Attack:       /*攻击*/                AttackUpdate();                break;        }    }    /*巡逻*/    private void PatrolUpdate()    {        if (player == null) /*如果玩家没有出现*/        {            if (timer >= 2f)    /*每隔2秒检查一次*/            {                timer = 0;                player = transform.parent.FindChild("Player(Clone)");          /*寻找玩家*/            }            timer += Time.deltaTime;        }        if (Vector3.Distance(transform.position, desPos) <= 1f)        {            FindNextPoint();        }        transform.LookAt(desPos);        /*向目标点移动*/        transform.Translate(Vector3.forward * Time.deltaTime * curSpeed);        if (player != null)        {            if (Vector3.Distance(transform.position, player.localPosition) <= 30f)            {                curState = FSMState.Chase;            }        }    }    /*追逐*/    private void ChaseUpdate()    {        desPos = player.localPosition;        /*向着目标点*/        transform.LookAt(desPos);        /*向目标点移动*/        transform.Translate(Vector3.forward * Time.deltaTime * curSpeed);        if (Vector3.Distance(transform.position, desPos) > 30f)        {            curState = FSMState.Patrol;        }        if (Vector3.Distance(transform.position, desPos) < 20f)        {            curState = FSMState.Attack;        }    }    /*攻击*/    private void AttackUpdate()    {        desPos = player.position;   /*玩家位置*/        if (timer >= 1)        {            if (Vector3.Distance(transform.position, desPos) <= 20f)            {                timer = 0;                GameObject go = Instantiate(buttle);                go.transform.SetParent(transform);                go.transform.localPosition = Vector3.zero;                Destroy(go, 0.5f);                iTween.MoveTo(go, desPos, 0.5f);            }        }        if (Vector3.Distance(transform.position, desPos) > 20f && Vector3.Distance(transform.position, desPos) <= 30f)        {            /*向着目标点*/            transform.LookAt(desPos);            /*向目标点移动*/            transform.Translate(Vector3.forward * Time.deltaTime * curSpeed);        }        if (Vector3.Distance(transform.position, desPos) > 30f)        {            curState = FSMState.Chase;        }        timer += Time.deltaTime;    }    /*寻找下一个巡逻点*/    private void  FindNextPoint()    {        int index=Random.Range(0, posList.Length);        desPos = posList[index].transform.position;    }}

这只是一个很简单的FSM,只是简单的使用了switch......case......完成,只是作为一种基础总结。


原创粉丝点击