Fsm适合用于:状态动画之间的跳转关系整理,降低耦合性,可扩展性增强。
直接进入正题。。。。
状态的抽象:三个状态
1,进入
2, 退出
3,循环
C层也就是控制层:
1,管理子状态
2,负责状态之间的交换
好的接下来上代码。。。。
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
(老三标签,新手,如有错误请前辈指点一下)
原文地址:https://www.cnblogs.com/-831/p/12312040.html