状态机FSM代码框架

这里写图片描述

左边摇杆控制英雄移动,右边三个按钮分别是三个动画,不用animation,纯代码写
最基础的有三个类,第一个是保存英雄状态的枚举

using UnityEngine;
using System.Collections;

#region  StateType 角色的状态类型
/// <summary>
/// 角色的状态类型
/// </summary>
public enum StateType { 
    None,
    Idle,
    Run,
    Skill1,
    Skill2,
    Skill3
}
#endregion

第二个基本的类
是一个抽象类,三个状态

using UnityEngine;
using System.Collections;

public abstract class FSMStateAbstract<T> {
    public virtual void OnEnter(T user){

    }

    public virtual void OnStay(T user){

    }

    public virtual void OnExit(T user){

    }
}

第三个也是代码最多的,状态管理器,负责添加状态,改变状态

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

public class FSMStateMgr<T>{
    public FSMStateAbstract<T> m_CurrentState;
    public FSMStateAbstract<T> m_PreviousState;

    public T m_User;

    public Dictionary<StateType, FSMStateAbstract<HeroCtr>> m_StaticDic = new Dictionary<StateType, FSMStateAbstract<HeroCtr>>();

    public FSMStateMgr(T user){
        m_CurrentState = null;
        m_PreviousState = null;
        m_User = user;
    }

    public void AddState(StateType stateType){
        if (m_StaticDic.ContainsKey (stateType))
            return;
        switch(stateType)
        {
            case StateType.None:
                break;
            case StateType.Idle:
                m_StaticDic.Add(stateType, new IdleState());
                break;
            case StateType.Run:
                m_StaticDic.Add(stateType, new RunState());
                break;
            case StateType.Skill1:
                m_StaticDic.Add(stateType, new SkillOneState());
                break;
            case StateType.Skill2:
                m_StaticDic.Add(stateType, new SkillTwoState());
                break;
            case StateType.Skill3:
                m_StaticDic.Add(stateType, new SkillThreeState());
                break;
            default:
                break;

        }
    }

    public void SetCurrentState(StateType stateType){
        if (m_StaticDic.ContainsKey (stateType))
            return;
        if (m_StaticDic.Count > 0)
            return;

        switch(stateType)
        {
        case StateType.None:
            break;
        case StateType.Idle:
            m_StaticDic.Add(stateType, new IdleState());
            break;
        case StateType.Run:
            m_StaticDic.Add(stateType, new RunState());
            break;
        case StateType.Skill1:
            m_StaticDic.Add(stateType, new SkillOneState());
            break;
        case StateType.Skill2:
            m_StaticDic.Add(stateType, new SkillTwoState());
            break;
        case StateType.Skill3:
            m_StaticDic.Add(stateType, new SkillThreeState());
            break;
        default:
            break;

        }

        m_CurrentState = m_StaticDic [stateType] as FSMStateAbstract<T>;
    }

    public void ChangeState(StateType stateType){
        FSMStateAbstract<T> newState = m_StaticDic [stateType] as FSMStateAbstract<T>;

        if (newState == null)
            return;

        if (m_CurrentState != null)
            m_CurrentState.OnExit (m_User);

        m_PreviousState = m_CurrentState;
        m_CurrentState = newState;

        m_CurrentState.OnEnter (m_User);
    }

    public void FSMUpdate(){
        if (m_CurrentState != null) {
            m_CurrentState.OnStay(m_User);
        }
    }
}

接下来的基础有了,开始写控制英雄,idle状态,run状态,还有三个方块执行的动画
一共是六个脚本

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

public class HeroCtr : MonoBehaviour {
    public EasyJoystick joyStick;

    public float moveSpeed = 3f;

    public Animation ani;

    public CharacterController con;

    public bool isGrounded;

    public List<string> animationList = new List<string>();

    public FSMStateMgr<HeroCtr> m_StateMachine;

    public bool isAttack = false;

    public Camera cam;

    // Use this for initialization
    void Start () {
        cam = GameObject.Find ("Main Camera").GetComponent<Camera>();

        foreach (AnimationState clip in ani) {
            animationList.Add(clip.name);
        }

        StartCoroutine (InitState());
    }

    void LateUpdate(){
        cam.transform.position = transform.position + new Vector3 (0, 3, -5);
        cam.transform.LookAt (transform);
    }

    IEnumerator InitState(){
        m_StateMachine = new FSMStateMgr<HeroCtr> (this);

        m_StateMachine.SetCurrentState (StateType.Idle);

        m_StateMachine.AddState (StateType.Run);
        m_StateMachine.AddState (StateType.Skill1);
        m_StateMachine.AddState (StateType.Skill2);
        m_StateMachine.AddState (StateType.Skill3);

        foreach (string aniName in animationList) {
            ani[aniName].wrapMode = WrapMode.Once;
        }

        yield return 0;
    }

    // Update is called once per frame
    void Update () {
        m_StateMachine.FSMUpdate ();

        DoMove ();
    }

    public void ClickButton(GameObject obj){
//      Debug.Log (obj.name);

        StateType stateType = StateType.None;

        switch (obj.name) 
        {
            case "Skill1":
                stateType = StateType.Skill1;
                break;

            case "Skill2":
                stateType = StateType.Skill2;
                break;

            case "Skill3":
                stateType = StateType.Skill3;
                break;

            default:
                break;
        }

//      Debug.Log (stateType);
        if (isAttack)
            return;

        m_StateMachine.ChangeState (stateType);
        isAttack = true;
    }

    void DoMove(){
        float x = joyStick.JoystickTouch.x;
        float z = joyStick.JoystickTouch.y;

        Vector3 moveDirection = Vector3.zero;

        if (x != 0 || z != 0) {
            transform.LookAt (transform.position + new Vector3 (x, 0, z));

            moveDirection = transform.TransformDirection (Vector3.forward);

            if(!isAttack)
                m_StateMachine.ChangeState (StateType.Run);
                con.Move (moveDirection * moveSpeed * Time.deltaTime);

        } else {
            if(!isAttack)
                m_StateMachine.ChangeState(StateType.Idle);
        }

        if (!isGrounded) {
            moveDirection += Vector3.down * 9.8f;
        }
        isGrounded = con.isGrounded;
    }
}

idle状态

using UnityEngine;
using System.Collections;

public class IdleState : FSMStateAbstract<HeroCtr> {
    public override void OnEnter (HeroCtr user)
    {
        user.ani.CrossFade ("Idle");
        base.OnEnter (user);
    }

    public override void OnStay (HeroCtr user)
    {
        if (!user.ani.IsPlaying ("Idle"))
            user.ani.CrossFade ("Idle");
        base.OnStay (user);
    }

    public override void OnExit (HeroCtr user)
    {
        base.OnExit (user);
    }
}

run状态

using UnityEngine;
using System.Collections;

public class RunState : FSMStateAbstract<HeroCtr> {

    public override void OnEnter (HeroCtr user)
    {
        user.ani.CrossFade ("Run");
        base.OnEnter (user);
    }

    public override void OnStay (HeroCtr user)
    {
        if (!user.ani.IsPlaying ("Run"))
            user.ani.CrossFade ("Run");

        base.OnStay (user);
    }

    public override void OnExit (HeroCtr user)
    {
        base.OnExit (user);
    }
}

然后是三个方块控制的动画

using UnityEngine;
using System.Collections;

public class SkillOneState : FSMStateAbstract<HeroCtr> {
    public override void OnEnter (HeroCtr user)
    {
        user.ani.CrossFade ("Skill1");
        base.OnEnter (user);


        Debug.Log ("SkillOne  SkillOne");
    }

    public override void OnStay (HeroCtr user)
    {
        if (!user.ani.IsPlaying ("Skill1"))
            OnExit (user);
        base.OnStay (user);
    }

    public override void OnExit (HeroCtr user)
    {
        base.OnExit (user);
        user.isAttack = false;
    }
}
using UnityEngine;
using System.Collections;

public class SkillThreeState : FSMStateAbstract<HeroCtr> {
    public override void OnEnter (HeroCtr user)
    {
        user.ani.CrossFade ("Skill3");
        base.OnEnter (user);

        Debug.Log ("SkillThree  SkillThree");
    }

    public override void OnStay (HeroCtr user)
    {
        if (!user.ani.IsPlaying ("Skill3"))
            OnExit (user);
        base.OnStay (user);
    }

    public override void OnExit (HeroCtr user)
    {
        base.OnExit (user);
        user.isAttack = false;
    }
}
using UnityEngine;
using System.Collections;

public class SkillTwoState : FSMStateAbstract<HeroCtr> {
    public override void OnEnter (HeroCtr user)
    {
        base.OnEnter (user);
        user.ani.CrossFade ("Skill2");

        Debug.Log ("SkillTwo SkillTwo");
    }

    public override void OnStay (HeroCtr user)
    {
        if (!user.ani.IsPlaying ("Skill2"))
            OnExit (user);
        base.OnStay (user);
    }

    public override void OnExit (HeroCtr user)
    {
        base.OnExit (user);
        user.isAttack = false;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值