欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Unity學(xué)習(xí)之FSM有限狀態(tài)機(jī)

 更新時間:2021年06月25日 12:09:43   作者:念丶小宇  
這篇文章主要介紹了Unity學(xué)習(xí)之FSM有限狀態(tài)機(jī),通過詳細(xì)的代碼案例來進(jìn)行解析說明,希望這篇文章對你有所幫助

前言:一個游戲里的一個人物會存在多種狀態(tài),那么就需要有一個專門管理這些狀態(tài)的類。不然會顯得雜亂無章,不易于后面狀態(tài)的增加或者減少。
思路:既然要方便管理,那么首先肯定得有個系統(tǒng)類(專門用來存放所有的狀態(tài)、狀態(tài)的增刪等功能);然后就是需要把所有的狀態(tài)都單獨寫一個類(已達(dá)到修改某個狀態(tài)的時候,其他狀態(tài)不會受到影響)。

狀態(tài)管理類:

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

public class FSMSystem 
{
    private Dictionary<StateID, FSMState> states = new Dictionary<StateID, FSMState>();

    private StateID currentStateID;
    private FSMState currentFSMState;

    public void Update(GameObject npc)
    {
        currentFSMState.Act(npc);
        currentFSMState.Reason(npc);
    }

    /// <summary>
    /// 添加狀態(tài)
    /// </summary>
    /// <param name="fSMState"></param>
    public void AddState(FSMState fSMState)
    {
        if (fSMState == null) return;

        //if (currentFSMState == null)
        //{
            currentStateID = fSMState.ID;
            currentFSMState = fSMState;
        //}
        if (states.ContainsKey(currentStateID)) return;
        states.Add(currentStateID, currentFSMState);
    }
    /// <summary>
    /// 刪除狀態(tài)
    /// </summary>
    /// <param name="stateID"></param>
    public void DeleteState(StateID stateID)
    {
        if (stateID == StateID.Null) return;
        if (!states.ContainsKey(stateID)) return;

        states.Remove(stateID);
    }
    

    /// <summary>
    /// 執(zhí)行狀態(tài)條件轉(zhuǎn)換
    /// </summary>
    /// <param name="transition"></param>
    public void PerformTransition(Transition transition)
    {
        if (transition == Transition.NullTransition) return;

        StateID stateID = currentFSMState.GetStateID(transition);
        if (stateID == StateID.Null) return;
        if (!states.ContainsKey(stateID)) return;

        FSMState fSMState = states[stateID];
        currentFSMState.StateExit();
        currentFSMState = fSMState;
        currentStateID = fSMState.ID;
        currentFSMState.StateEnter();
    }
}

狀態(tài)基類:

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

public enum Transition
{
    NullTransition,
    SeePlayer,//發(fā)現(xiàn)玩家
    LostPlayer,//玩家脫離視野范圍
    AttackPlayer,//攻擊玩家
}
public enum StateID
{
    Null,
    Chase,//追逐
    Patrol,//巡邏
    Attack,//攻擊
}
public abstract class FSMState
{
    protected Transition transition;

    protected StateID stateID;
    protected FSMSystem fSM;
    public StateID ID
    {
        get { return stateID; }
    }

    protected Dictionary<Transition, StateID> dic = new Dictionary<Transition, StateID>();

    public FSMState(FSMSystem fSM)
    {
        this.fSM = fSM;
    }

    /// <summary>
    /// 增加狀態(tài)
    /// </summary>
    /// <param name="transition"></param>
    /// <param name="stateID"></param>
    public void AddTransition(Transition transition, StateID stateID)
    {
        if (transition == Transition.NullTransition) return;
        if (stateID == StateID.Null) return;
        if (dic.ContainsKey(transition)) return;

        dic.Add(transition, stateID);
    }
    /// <summary>
    /// 刪除狀態(tài)
    /// </summary>
    /// <param name="transition"></param>
    public void DeleteTransition(Transition transition)
    {
        if (transition == Transition.NullTransition) return;
        if (!dic.ContainsKey(transition)) return;

        dic.Remove(transition);
    }
    /// <summary>
    /// 獲取狀態(tài)
    /// </summary>
    /// <param name="transition"></param>
    /// <returns></returns>
    public StateID GetStateID(Transition transition)
    {
        if (transition == Transition.NullTransition) return StateID.Null;
        if (!dic.ContainsKey(transition)) return StateID.Null;
        return dic[transition];
    }

    /// <summary>
    /// 進(jìn)入狀態(tài)
    /// </summary>
    public virtual void StateEnter() { }
    /// <summary>
    /// 退出狀態(tài)
    /// </summary>
    public virtual void StateExit() { }

    /// <summary>
    /// 狀態(tài)持續(xù)中,,,
    /// </summary>
    /// <param name="npc"></param>
    public abstract void Act(GameObject npc);
    /// <summary>
    /// 狀態(tài)退出前,,,
    /// </summary>
    /// <param name="npc"></param>
    public abstract void Reason(GameObject npc);
}

巡邏狀態(tài):

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

/// <summary>
/// 巡邏狀態(tài)
/// </summary>
public class PatrolState : FSMState
{
    /// <summary>
    /// 巡邏路徑點集合
    /// </summary>
    private Transform[] paths;
    /// <summary>
    /// 當(dāng)前巡邏路徑點索引
    /// </summary>
    private int index = 0;
    /// <summary>
    /// 移動速度
    /// </summary>
    private float moveSpeed = 0.5f;
    /// <summary>
    /// 玩家
    /// </summary>
    private Transform player;
    public PatrolState(FSMSystem fSM, Transform player) : base(fSM)
    {
        this.player = player;
        paths = GameObject.Find("Path").GetComponentsInChildren<Transform>();
        stateID = StateID.Patrol;
    }

    public override void Act(GameObject npc)
    {
        npc.transform.LookAt(paths[index].position);
        npc.transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed);
        if (Vector3.Distance(npc.transform.position, paths[index].position) < 1)
        {
            index++;
            index %= paths.Length;
        }
    }

    public override void Reason(GameObject npc)
    {
        npc.GetComponent<Animator>().SetFloat("Speed", moveSpeed );
        if (Vector3.Distance(player.position, npc.transform.position) < 10)
        {
            fSM.PerformTransition(Transition.SeePlayer);
        }
    }
}

追逐狀態(tài):

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

/// <summary>
/// 追逐狀態(tài)
/// </summary>
public class ChaseState : FSMState
{
    /// <summary>
    /// 移動速度
    /// </summary>
    private float moveSpeed = 2f;
    /// <summary>
    /// 玩家
    /// </summary>
    private Transform player;
    public ChaseState(FSMSystem fSM, Transform player) : base(fSM)
    {
        stateID = StateID.Chase;
        this. player = player;
    }

    public override void Act(GameObject npc)
    {
        npc.transform.LookAt(player.position);
        npc.transform.Translate(Vector3.forward * Time.deltaTime * moveSpeed);
    }

    public override void Reason(GameObject npc)
    {
        npc.GetComponent<Animator>().SetFloat("Speed", moveSpeed / 2);
        if (Vector3.Distance(player.position, npc.transform.position) >= 10)
        {
            fSM.PerformTransition(Transition.LostPlayer);
        }
        else if (Vector3.Distance(player.position, npc.transform.position) <= 1f )
        {
            fSM.PerformTransition(Transition.AttackPlayer);
        }
    }
}

攻擊狀態(tài):

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

/// <summary>
/// 攻擊狀態(tài)
/// </summary>
public class AttackState : FSMState
{
    /// <summary>
    /// 玩家
    /// </summary>
    private Transform player;
    public AttackState(FSMSystem fSM, Transform player) : base(fSM)
    {
        stateID = StateID.Attack;
        this.player = player;
    }
    public override void Act(GameObject npc)
    {

    }

    public override void Reason(GameObject npc)
    {
        if (Vector3.Distance(player.position, npc.transform.position) > 1f)
        {
            if (Vector3.Distance(player.position, npc.transform.position) >= 10)
            {
                fSM.PerformTransition(Transition.LostPlayer);
            }
            else if (Vector3.Distance(player.position, npc.transform.position) < 10)
            {
                fSM.PerformTransition(Transition.SeePlayer);
            }
            return;
        }
        npc.GetComponent<Animator>().SetTrigger("Attack01");
    }
}

狀態(tài)持有者實現(xiàn)類:

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

public class Enemy : MonoBehaviour
{
    private FSMSystem fSM;
    private Transform player;
    private void Start()
    {
        fSM = new FSMSystem();
        FSMState patrolState = new PatrolState(fSM, player);
        patrolState.AddTransition(Transition.SeePlayer, StateID.Chase);
        patrolState.AddTransition(Transition.AttackPlayer, StateID.Attack);
        //patrolState.AddTransition(Transition.LostPlayer, StateID.Patrol);

        FSMState chaseState = new ChaseState(fSM, player);
        chaseState.AddTransition(Transition.LostPlayer, StateID.Patrol);
        chaseState.AddTransition(Transition.AttackPlayer, StateID.Attack);
        //chaseState.AddTransition(Transition.SeePlayer, StateID.Chase);

        FSMState attackState = new AttackState(fSM, player);
        attackState.AddTransition(Transition.SeePlayer, StateID.Chase);
        attackState.AddTransition(Transition.LostPlayer, StateID.Patrol);
        //attackState.AddTransition(Transition.AttackPlayer, StateID.Attack);

        fSM.AddState(patrolState);
        fSM.AddState(chaseState);
        fSM.AddState(attackState);
    }

    private void Update()
    {
        fSM.Update(gameObject);
    }
}

到此這篇關(guān)于Unity學(xué)習(xí)之FSM有限狀態(tài)機(jī)的文章就介紹到這了,更多相關(guān)UnityFSM有限狀態(tài)機(jī)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C#8.0中的索引與范圍功能介紹

    C#8.0中的索引與范圍功能介紹

    這篇文章介紹了C#8.0中的索引與范圍功能,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-01-01
  • 詳解C#中三個關(guān)鍵字params,Ref,out

    詳解C#中三個關(guān)鍵字params,Ref,out

    本文主要討論params關(guān)鍵字,ref關(guān)鍵字,out關(guān)鍵字。非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2017-05-05
  • 簡單實現(xiàn)C#窗體程序判斷是否閏年

    簡單實現(xiàn)C#窗體程序判斷是否閏年

    這篇文章主要介紹了簡單實現(xiàn)C#窗體程序判斷是否閏年的相關(guān)代碼,禁止窗體調(diào)整大小,關(guān)閉窗體前的判斷,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Windows Form 分頁 具體實現(xiàn)

    Windows Form 分頁 具體實現(xiàn)

    其實功能實現(xiàn)很簡單。我做的是一個通用的分頁控件。項目時間很緊,可能有點粗糙。歡迎大家斧正。不說了直接貼代碼吧
    2013-12-12
  • c# winform treelistview的使用(treegridview)實例詳解

    c# winform treelistview的使用(treegridview)實例詳解

    這篇文章主要介紹了c# winform treelistview的使用(treegridview),本文通過實例代碼給大家詳細(xì)介紹,需要的朋友可以參考下
    2017-12-12
  • c#使用FreeSql生產(chǎn)環(huán)境時自動升級備份數(shù)據(jù)庫

    c#使用FreeSql生產(chǎn)環(huán)境時自動升級備份數(shù)據(jù)庫

    使用FreeSql,包含所有的ORM數(shù)據(jù)庫,都會存在這樣的問題。在codefirst模式下,根據(jù)代碼自動更新數(shù)據(jù)庫,都建議不要在生產(chǎn)環(huán)境使用。因為容易丟失數(shù)據(jù),本文提供一種自動更新數(shù)據(jù)庫的解決的思路:在判斷需要升級時,才自動升級,同時升級前先備份數(shù)據(jù)庫
    2021-06-06
  • C#中跨線程訪問控件問題解決方案分享

    C#中跨線程訪問控件問題解決方案分享

    這篇文章主要介紹了C#中跨線程訪問控件問題解決方案,有需要的朋友可以參考一下
    2013-11-11
  • c#實現(xiàn)字符串反序輸出字符串的實例

    c#實現(xiàn)字符串反序輸出字符串的實例

    下面小編就為大家分享一篇c#實現(xiàn)字符串反序輸出字符串的實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2017-12-12
  • C#實現(xiàn)炫酷啟動圖-動態(tài)進(jìn)度條效果

    C#實現(xiàn)炫酷啟動圖-動態(tài)進(jìn)度條效果

    這篇文章主要介紹了基于C#實現(xiàn)炫酷啟動圖-動態(tài)進(jìn)度條 效果,本文通過實例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-05-05
  • 在Unity中實現(xiàn)簡單的偽時間同步

    在Unity中實現(xiàn)簡單的偽時間同步

    這篇文章主要介紹了在Unity中實現(xiàn)簡單的偽時間同步,為什么說是偽同步呢,因為僅僅是獲取的數(shù)據(jù)庫所在服務(wù)器的系統(tǒng)時間,分享給大家,有需要的小伙伴可以參考下
    2015-03-03

最新評論