Fsm有限狀態機深刻淺析代碼

Fsm適合用於:狀態動畫之間的跳轉關係整理,下降耦合性,可擴展性加強。ide

直接進入正題。。。。函數

狀態的抽象:三個狀態動畫

1,進入spa

2, 退出pwa

3,循環代理

C層也就是控制層:orm

1,管理子狀態blog

2,負責狀態之間的交換事件

好的接下來上代碼。。。。it

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

public abstract class FsmBase : MonoBehaviour {
//進入
public abstract void OnEnter();
//退出
public abstract void OnLeave();
//循環
public abstract void Update();

}
//控制層
public class FsmManager
{
FsmBase[] allState;

sbyte stateIndex;//長度

sbyte curIndex;//當前處在某個狀態下

//構造函數初始化
public FsmManager(sbyte stateCount)
{
allState = new FsmBase[stateCount];

stateIndex = -1;

curIndex = -1;
}

 

//添加狀態
public void AddState(FsmBase state)
{

if (stateIndex<allState.Length)//作個範圍限制
{
stateIndex++;

allState[stateIndex] = state;
}

}
//交換狀態
public void ChangeState(sbyte stateNuber)
{
stateNuber = (sbyte)(stateNuber % allState.Length);//範圍限制

if (curIndex!=-1)//表示有狀態
{
allState[curIndex].OnLeave();//退出當前狀態

curIndex = stateNuber;

allState[curIndex].OnEnter();//進入下一個狀態
}
else
{
curIndex = stateNuber;

allState[curIndex].OnEnter();//進入
}
}

//循環
public void Upatate()
{
if (curIndex!=-1)
{
allState[curIndex].Update();
}
}
}

上面有兩個類抽象類和管理

抽象裏面有三個字段狀態;

管理類裏面具體實現這三個的

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

using UnityEngine.Events;
//狀態的類 類裏面適合處理每一個動畫狀態的類
public class IdleAnimator : FsmBase
{
Animator animator;

private float timeCount;//處理動畫的

UnityAction<sbyte> callBack;//回調

public IdleAnimator(Animator tempAnimal,UnityAction<sbyte> tempBack)
{
animator = tempAnimal;

callBack = tempBack;
}
//進入
public override void OnEnter()
{
animator.SetInteger("動畫1", 1);
}
//退出
public override void OnLeave()
{

}
//循環
public override void Update()
{
//簡單寫個動畫計時器 表示在這處理動畫的問題
timeCount += Time.deltaTime;
if (timeCount>=1)
{
timeCount = 0;

//animator.SetInteger 不能直接在這跳轉 應該是以下操做
//切換到idle模式狀態 這裏啓用了一個代理
callBack((sbyte)OrcCtrl.AnimalState.Idle);
}
}
}
public class RunAnimator : FsmBase
{
Animator animator;

public RunAnimator(Animator tempAnimal)
{
animator = tempAnimal;
}
//進入
public override void OnEnter()
{
animator.SetInteger("動畫2", 2);
}
//退出
public override void OnLeave()
{

}
//循環
public override void Update()
{

}
}
public class WalkAnimator : FsmBase
{
Animator animator;

public WalkAnimator(Animator tempAnimal)
{
animator = tempAnimal;
}
//進入
public override void OnEnter()
{
animator.SetInteger("動畫3", 3);
}
//退出
public override void OnLeave()
{

}
//循環
public override void Update()
{

}
}
public class AttackAnimator : FsmBase
{
Animator animator;

public AttackAnimator(Animator tempAnimal)
{
animator = tempAnimal;
}
//進入
public override void OnEnter()
{
animator.SetInteger("動畫4", 4);
}
//退出
public override void OnLeave()
{

}
//循環
public override void Update()
{

}
}

每個動畫狀態作一個類

在每一個動畫的類裏能夠作這個動畫的具體事件

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

public class OrcCtrl : MonoBehaviour {

FsmManager fsmMangager;

public enum AnimalState
{
Idle,
Run,
Walk,
Attack,
//能夠在這擴展
MaxValue
}
//代理
public void ChangeState(sbyte stateIndex)
{
fsmMangager.ChangeState(stateIndex);
}

void Start () {

fsmMangager = new FsmManager((sbyte)AnimalState.MaxValue);//方便擴展

Animator tempanimator = transform.GetComponent<Animator>();
//添加動畫操做 1,idle
IdleAnimator tempidleAnimator = new IdleAnimator(tempanimator,ChangeState);
fsmMangager.AddState(tempidleAnimator);
//2,Run
RunAnimator temprunAnimator = new RunAnimator(tempanimator);
fsmMangager.AddState(temprunAnimator);
//3,walk
WalkAnimator tempwalkAnimator = new WalkAnimator(tempanimator);
fsmMangager.AddState(tempwalkAnimator);
//4,Attack
AttackAnimator tempattackAnimator = new AttackAnimator(tempanimator);
fsmMangager.AddState(tempattackAnimator);

}

// Update is called once per frame
void Update () {

//動畫在這的一系列操做
if (Input.GetKeyDown(KeyCode.A))
{
//交換狀態
fsmMangager.ChangeState((sbyte)AnimalState.Run);
}
if (Input.GetKeyDown(KeyCode.B))
{
//交換狀態
fsmMangager.ChangeState((sbyte)AnimalState.Attack);
}
fsmMangager.Upatate();
}
}

 

 

 

這裏主要是添加動畫狀態 腳本掛載須要的物體上

 

 相似這個 而後Event用int idle是1

 

(老三標籤,新手,若有錯誤請前輩指點一下)

相關文章
相關標籤/搜索