zoukankan      html  css  js  c++  java
  • Unity c# 状态机的简单入门

    状态机模式在unity中作用是非常大的,可以实现角色的移动和场景的跳转,包括一些动画的播放,在很多unity框架中也是很常见的,发散思维广阔,下面是简单的状态机的实现,有注释

    using System.Collections;
    using System.Collections.Generic;
    using UnityEngine;
    public enum StateType
    {
    Idle,
    Die,
    Move,
    }

    public abstract class StateObject
    {
    protected StateManger state;
    public StateObject(StateManger _sm)
    {
    state = _sm;
    }
    //进入方法
    public abstract void EnterState();
    //离开方法
    public abstract void ExiState();
    //持续更新方法
    public abstract void UpdateState();
    }
    //站着状态
    public class IdleState : StateObject
    {
    public IdleState(StateManger state):base(state)
    {

    }

    public override void EnterState()
    {
    Debug.Log("进入站着状态");
    }

    public override void ExiState()
    {
    Debug.Log("离开站着状态");
    }

    public override void UpdateState()
    {
    Debug.Log("等待站着状态");
    if (Input .GetKey(KeyCode.M))
    {
    Debug.Log("按下咯");
    state.ChangeState("Move");
    }
    if (Input.GetKey(KeyCode.D))
    {
    state.ChangeState("Die");
    }
    }
    }
    //移动状态
    public class MoveState : StateObject
    {
    public MoveState(StateManger state):base(state)
    {

    }
    public override void EnterState()
    {
    Debug.Log("进入移动状态");
    }

    public override void ExiState()
    {
    Debug.Log("离开移动状态");
    }

    public override void UpdateState()
    {
    Debug.Log("进入移动更新状态");
    if (Input.GetKey(KeyCode.D))
    {
    state.ChangeState("Die");
    }
    if (Input.GetKey(KeyCode.I))
    {
    state.ChangeState("Idle");
    }
    }
    }
    //死亡状态
    public class DieState : StateObject
    {
    public DieState(StateManger state) : base(state)
    {

    }
    public override void EnterState()
    {
    Debug.Log("进入死亡状态");
    }

    public override void ExiState()
    {
    Debug.Log("离开死亡状态");
    }

    public override void UpdateState()
    {
    Debug.Log("进入死亡更新状态");

    if (Input.GetKey(KeyCode.I))
    {
    state.ChangeState("Idle");
    }
    }
    }
    public class StateManger {
    //字典存储状态
    Dictionary<string, StateObject> dic = new Dictionary<string, StateObject>();
    //当前状态
    StateObject currentstate;
    //注册状态
    public void Region(string statename,StateObject state)
    {
    //判断字典中是否存在这个键
    if (!dic.ContainsKey(statename))
    {
    dic.Add(statename,state);
    }
    }
    //设置默认状态
    public void SetDefat(string statename)
    {
    //判断字典中是否存在这个状态
    if (dic.ContainsKey(statename))
    {
    //存在就赋值给currentstate
    currentstate = dic[statename];
    //调用当前状态的进入(EnterState)方法
    currentstate.EnterState();
    }
    }
    //改变状态
    public void ChangeState(string statename)
    {
    //判断字典中是否存在这个状态
    if (dic.ContainsKey(statename))
    {
    //当前状态是否为空
    if (currentstate!=null)
    {
    //调用上一个状态的离开方法
    currentstate.ExiState();
    //把取到的状态赋值给currentstate
    currentstate = dic[statename];
    //调用取到状态的进入方法
    currentstate.EnterState();
    }
    }
    }
    //更新状态
    public void UpdateState()
    {
    Debug.Log("更新状态");
    if (currentstate!=null)
    {
    //当前状态的UpdateState方法
    currentstate.UpdateState();
    }
    }
    }
    public class FMSC : MonoBehaviour {
    StateManger sm = new StateManger();
    // Use this for initialization
    void Start () {
    //注册站着的方法
    sm.Region("Idle",new IdleState(sm));
    //注册死亡的方法
    sm.Region("Die",new DieState(sm));
    //注册移动的方法
    sm.Region("Move",new MoveState(sm));
    //设置默认状态
    sm.SetDefat("Idle");
    }

    // Update is called once per frame
    void Update () {
    //持续调用当前状态的UpdateState方法
    sm.UpdateState();
    }
    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189

    每个状态都是有自己的方法,在每个状态有不同要做的事情,减少代码的耦合性
    --------------------- 

  • 相关阅读:
    解决CSS图片底部3像素问题总结
    常用伪元素及content属性值的使用
    javascript中用正则表达式判断是否为汉字及常用的判断
    javascript 正则表达式
    js常用事件
    js动态获取select选中的option
    innerHTML innerText与outerHTML间的区别
    vue的生命周期(又称钩子函数)----以及vue1.0版本与vue2.0版本生命周期的不同
    JavaScript实现表单验证_02
    JavaScript数组实现图片轮播
  • 原文地址:https://www.cnblogs.com/hyhy904/p/11001406.html
Copyright © 2011-2022 走看看