当前位置:网站首页>FSM state machine
FSM state machine
2022-06-13 06:53:00 【renwen1579】
FSM Finite state machine
Animation state machine can only be used for animation
The normal speed of the game 、2 Double speed 、 Pause
Eat the chicken
Half squat Crawling state Walk

Dictionaries
entrust

There is a return value return bool
A coroutine must inherit monobehavior Class can execute




The dictionary can update the status of multiple events at the same time


A Functions and B Functions execute simultaneously

Nesting of state machines
17:00
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;namespace FSMFrame
{
public class State {
public State(string name){
StateName = name;
TransitionStates = new Dictionary<string, Func<bool>>();
}
/// <summary>
/// Status name
/// </summary>
private string StateName { get; set; }
#region Transition States Control
/// <summary>
/// Other states that the current state can switch , What is passed in is a delegate , Return is bool value
/// </summary>
private Dictionary<string, Func<bool>> TransitionStates { get; set; }
/// <summary>
/// Registration status switching
/// </summary>
/// <param name="stateName"> Name of the state to be switched </param>
/// <param name="condition"> Switching conditions </param>
public void RegisterTransitionState(String stateName,Func<bool> condition) {
if (!TransitionStates.ContainsKey(stateName))
{
// add to
TransitionStates.Add(stateName, condition);
}
else {
// to update
TransitionStates[stateName] = condition;
}
}
/// <summary>
/// Unregister the switch state
/// </summary>
/// <param name="stateName"></param>
public void UnRegisterTransitionState(string stateName) {
if (TransitionStates.ContainsKey(stateName)) {
// remove
TransitionStates.Remove(stateName);
}
}
#endregion
#region State Machine Event
/// <summary>
/// Status entry event
/// </summary>
public event Action<object[]> OnStateEnter;
/// <summary>
/// Status and new events 【 During the State , Keep calling 】
/// </summary>
public event Action<object[]> OnStateUpdate;
/// <summary>
/// Leave status event
/// </summary>
public event Action<object[]> OnStateExit;
/// <summary>
/// Enter the state of
/// </summary>
/// <param name="paramters"></param>
public void EnterState(object[] enterEventparamters,object[] updateEventParamters) {
if (OnStateEnter != null) {
// Execute the event entering the State
OnStateEnter(enterEventparamters);
}
// Bind the update event of the current state , For later execution
MonoHelper.Instance.AddUpdateEvent(StateName, OnStateUpdate,updateEventParamters);
}
/// <summary>
/// Out of state
/// </summary>
/// <param name="paramters"></param>
public void ExitState(object[] paramters) {
// Unbind the update event of the current state , So that execution can be stopped later
MonoHelper.Instance.RemoveUpdateEvent(StateName);
if (OnStateExit != null) {
// Execute leave status event
OnStateExit(paramters);
}
}
#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSMFrame
{
public class MonoHelper : MonoBehaviour
{
/// <summary>
/// Status update module
/// </summary>
class StateUpdateModule {
/// <summary>
/// Status name
/// </summary>
//public string stateName;
/// <summary>
/// Status update event
/// </summary>
public Action<object[]> stateUpdateEvent;
/// <summary>
/// Parameters that trigger the status update event
/// </summary>
public object[] stateUpdateEventParamters;
public StateUpdateModule(Action<object[]> e, object[] paras) {
stateUpdateEvent = e;
stateUpdateEventParamters = paras;
}
}
/// <summary>
/// Singleton script
/// </summary>
public static MonoHelper Instance;
private void Awake()
{
Instance = this;
StateUpdateModuleDic = new Dictionary<string, StateUpdateModule>();
}
/// <summary>
/// Update the time interval of event execution
/// </summary>
[Header(" Update the time interval of event execution ")]
public float invokeInterval = -1;/// <summary>
/// Status update module dictionary
/// </summary>
private Dictionary<string, StateUpdateModule> StateUpdateModuleDic;
/// <summary>
/// Add update event
/// </summary>
/// <param name="stateName"> Status name </param>
/// <param name="updateEvent"> Update Events </param>
/// <param name="updateEventParamters"> Update the parameters used in the event execution </param>
public void AddUpdateEvent(string stateName, Action<object[]> updateEvent, object[] updateEventParamters) {
// If the state exists in the dictionary
if (StateUpdateModuleDic.ContainsKey(stateName))
{
// to update Update Events and parameters
StateUpdateModuleDic[stateName] = new StateUpdateModule(updateEvent, updateEventParamters);
}
else {
// add to Update Events and parameters
StateUpdateModuleDic.Add(stateName, new StateUpdateModule(updateEvent, updateEventParamters));
}
}
/// <summary>
/// Remove update event
/// </summary>
/// <param name="stateName"></param>
public void RemoveUpdateEvent(string stateName) {
if (StateUpdateModuleDic.ContainsKey(stateName)) {
// remove
StateUpdateModuleDic.Remove(stateName);
}}
/// <summary>
/// test
/// </summary>
/// <returns></returns>
private void Test1(object[] objs) {
Debug.Log("Test");
Debug.Log("Objs:"+objs.Length);
}
private void Test2(object[] objs)
{
Debug.Log("Test2" + objs.Length);
}
private IEnumerator Start()
{
//Test:
AddUpdateEvent(stateName:"TestState",updateEvent:Test1,updateEventParamters:new object[] { 1,2,3});
AddUpdateEvent(stateName: "NewTestState", updateEvent: Test2, updateEventParamters: new object[] { 4,5 });
while (true) {
if (invokeInterval <= 0)
{
// Wait a frame
yield return 0;}
else {
// Wait a time interval
yield return new WaitForSeconds(invokeInterval);
}
// Execution event
foreach (KeyValuePair<string,StateUpdateModule> updateModule in StateUpdateModuleDic)
{
if (updateModule.Value.stateUpdateEvent != null) {
// Call each event in the dictionary , And pass the parameters
updateModule.Value.stateUpdateEvent(updateModule.Value.stateUpdateEventParamters);
}
}
}
}}
}
Lambda expression .
Lambda Expression is C#3.0 New content of , If you learned before C#2.0, It's not surprising that I don't know .
Let me give you an example .
for example , I define a delegate :
delegate int Method(int a, int b);
Define one more method :
int Add(int a, int b)
{
return a + b;
}
I might need to call a method through a delegate like this :
Method m += Add;
Console.WriteLine(m(2, 3));
====================================================
But if use Lambda expression :
Method m += (a ,b) => a + b;
Console.WriteLine(m(2, 3));
You can omit the definition of the method .
actually , Lambda Expressions simply simplify the syntax of anonymous methods .
attach C# 2.0 Anonymous method syntax :
Method m += delegate(int a, int b) { return a + b; };
Console.WriteLine(m(2, 3));
*******************************************************************************
C# in += (s, e) => What do these characters mean
public MainWindow()
{
InitializeComponent();
this.Loaded += (s, e) => DiscoverKinectSensor();
this.Unloaded += (s, e) => this.kinect = null;
}
=========================================================================


state It could be statemachine, because statemachine yes state Subclasses of

Can achieve recursion , One state machine manages several subclasses of state machines

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSMFrame
{
public class StateMachine : State
{
#region Manager States
/// <summary>
/// The state of being managed
/// </summary>
private Dictionary<string, State> manageredStates;
/// <summary>
/// Default state
/// </summary>
private State defaultState;
/// <summary>
/// current state
/// </summary>
private State currentState;
public StateMachine(string name) : base(name)
{
manageredStates = new Dictionary<string, State>();
// Bind initial event
StateMachineEventBind();
}private void StateMachineEventBind() {
OnStateUpdate += CheckCurrentSTateTransition;
}
/// <summary>
/// Add state
/// </summary>
/// <param name="stateName"></param>
/// // Add... By status name
public State AddState(string stateName) {
if (IsRun)
{
Debug.LogWarning(" The status has been started , Status deletion is not allowed ");
return null;
}
if (manageredStates.ContainsKey(stateName))
{
Debug.LogWarning(" The state already exists ");
return manageredStates[stateName];
}
// Create a state of
State crtState = new State(stateName);
// Add state
manageredStates.Add(stateName, crtState);
// The currently added state is the first state
if (manageredStates.Count == 1) {
// The current state is the default state
defaultState = crtState;
}
return crtState;
}
/// <summary>
/// Add state
/// </summary>
/// <param name="crtState"></param>
public void AddState(State crtState) {
if (manageredStates.ContainsKey(crtState.StateName))
{
Debug.LogWarning(" The state already exists ");
return;
}
// Add state
manageredStates.Add(crtState.StateName, crtState);
// The currently added state is the first state
if (manageredStates.Count == 1)
{
// The current state is the default state
defaultState = crtState;
}
}
/// <summary>
/// Remove state
/// </summary>
/// <param name="stateName"></param>
public void RemoveState(string stateName) {
if (IsRun)
{
Debug.LogWarning(" The status has been started , Status deletion is not allowed ");
return;
}
// If the current state is in the state machine , And not the current state
if (manageredStates.ContainsKey(stateName)&&manageredStates[stateName]!=currentState) {
// Current status to delete
State crtState = manageredStates[stateName];
// Remove state
manageredStates.Remove(stateName);
// If the current state is the default state
if (manageredStates[stateName] == defaultState) {
// Clear the last default state
defaultState = null;
// Select the new default state
ChooseNewDefaultState();
}
}
}
/// <summary>
/// Select the new default state
/// </summary>
private void ChooseNewDefaultState() {
foreach (KeyValuePair<string,State> item in manageredStates) {
// Traverse to the first state set to the default state
defaultState = item.Value;
return;
}
}
#endregion#region State Machine Event
/// <summary>
/// The entry of the state machine
/// </summary>
/// <param name="enterEventparamters"></param>
/// <param name="updateEventParamters"></param>
public override void EnterState(object[] enterEventparamters, object[] updateEventParamters)
{
// First execute the entry event of the current state machine
base.EnterState(enterEventparamters, updateEventParamters);
// When executing the entry of sub state
// Determine whether there is a default state
if (defaultState == null) {
return;
}
// At this time, the current state is the default state
currentState = defaultState;
// Current state execution entry event [ Enter the default sub state ]
currentState.EnterState(enterEventparamters, updateEventParamters);
}
/// <summary>
/// The departure of the state machine
/// </summary>
/// <param name="paramters"></param>
public override void ExitState(object[] paramters)
{ // If the status is not empty
if (currentState != null)
{
// Leave the current status first
currentState.ExitState(paramters);
}
// The state machine leaves
base.ExitState(paramters);
}
#endregion#region State Machine Check State Transition
/// <summary>
/// Check whether the current state meets the transition conditions , Meet and transition
/// </summary>
private void CheckCurrentSTateTransition(object[] objs) {
// Detect transition events
string targetState=currentState.CheckTransition();
// When the current state reaches the transition event, it meets
if (targetState != null) {
// Transition to a new state
TransitionToState(targetState);
}
}private void TransitionToState(string targetStateName) {
// Whether the state to be transitioned is managed by the current state machine
if (manageredStates.ContainsKey(targetStateName)) {
// The current status leaves
currentState.ExitState(null);
// Switch the current state to the new state
currentState = manageredStates[targetStateName];
// The new current state execution enters
currentState.EnterState(null, null);
}
}
#endregion
}
}
All the code
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;namespace FSMFrame
{
public class State {
public State(string name){
StateName = name;
TransitionStates = new Dictionary<string, Func<bool>>();
// Bind base callback
StateBaseEventBind();
}
/// <summary>
/// Status name
/// </summary>
public string StateName { get; set; }
/// <summary>
/// Mark whether the current state is already executing
/// </summary>
public bool IsRun { get; set; }
#region State Base EventBinding
private void StateBaseEventBind()
{
// Enter the status flag
OnStateEnter += objects => { IsRun = true; };
OnStateExit += objects => { IsRun = false; };
}#endregion
#region Transition States Control
/// <summary>
/// Other states that the current state can switch , What is passed in is a delegate , Return is bool value
/// </summary>
private Dictionary<string, Func<bool>> TransitionStates { get; set; }
/// <summary>
/// Registration status switching
/// </summary>
/// <param name="stateName"> Name of the state to be switched </param>
/// <param name="condition"> Switching conditions </param>
public void RegisterTransitionState(String stateName,Func<bool> condition) {
if (!TransitionStates.ContainsKey(stateName))
{
// add to
TransitionStates.Add(stateName, condition);
}
else {
// to update
TransitionStates[stateName] = condition;
}
}
/// <summary>
/// Unregister the switch state
/// </summary>
/// <param name="stateName"></param>
public void UnRegisterTransitionState(string stateName) {
if (TransitionStates.ContainsKey(stateName)) {
// remove
TransitionStates.Remove(stateName);
}
}
#endregion
#region State Machine Event
/// <summary>
/// Status entry event
/// </summary>
public event Action<object[]> OnStateEnter;
/// <summary>
/// Status and new events 【 During the State , Keep calling 】
/// </summary>
public event Action<object[]> OnStateUpdate;
/// <summary>
/// Leave status event
/// </summary>
public event Action<object[]> OnStateExit;
/// <summary>
/// Enter the state of
/// </summary>
/// <param name="paramters"></param>
public virtual void EnterState(object[] enterEventparamters,object[] updateEventParamters) {
if (OnStateEnter != null) {
// Execute the event entering the State
OnStateEnter(enterEventparamters);
}
// Bind the update event of the current state , For later execution
MonoHelper.Instance.AddUpdateEvent(StateName, OnStateUpdate,updateEventParamters);
}
/// <summary>
/// Out of state
/// </summary>
/// <param name="paramters"></param>
public virtual void ExitState(object[] paramters) {
// Unbind the update event of the current state , So that execution can be stopped later
MonoHelper.Instance.RemoveUpdateEvent(StateName);
if (OnStateExit != null) {
// Execute leave status event
OnStateExit(paramters);
}
}
#endregion#region Check Transition
/// <summary>
/// Detect state transition
/// </summary>
/// <returns></returns>
public string CheckTransition() {
foreach (KeyValuePair<string, Func<bool>> item in TransitionStates)
{ // Execute judgment conditions
if (item.Value())
{
// Conditions met , Transition state
return item.Key;
}
}
return null;
}#endregion
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSMFrame
{
public class MonoHelper : MonoBehaviour
{
/// <summary>
/// Status update module
/// </summary>
class StateUpdateModule {
/// <summary>
/// Status name
/// </summary>
//public string stateName;
/// <summary>
/// Status update event
/// </summary>
public Action<object[]> stateUpdateEvent;
/// <summary>
/// Parameters that trigger the status update event
/// </summary>
public object[] stateUpdateEventParamters;
public StateUpdateModule(Action<object[]> e, object[] paras) {
stateUpdateEvent = e;
stateUpdateEventParamters = paras;
}
}
/// <summary>
/// Singleton script
/// </summary>
public static MonoHelper Instance;
private void Awake()
{
Instance = this;
StateUpdateModuleDic = new Dictionary<string, StateUpdateModule>();
}
/// <summary>
/// Update the time interval of event execution
/// </summary>
[Header(" Update the time interval of event execution ")]
public float invokeInterval = -1;/// <summary>
/// Status update module dictionary
/// </summary>
private Dictionary<string, StateUpdateModule> StateUpdateModuleDic;
/// <summary>
/// Status update module array
/// </summary>
private StateUpdateModule[] stateUpdateModuleArray;private void DicToArray()
{
// Instantiate arrays
stateUpdateModuleArray = new StateUpdateModule[StateUpdateModuleDic.Count];
// Counter
int counter = 0;
foreach (KeyValuePair<string, StateUpdateModule> item in StateUpdateModuleDic) {
// Module event object
stateUpdateModuleArray[counter] = item.Value;
// Counter increment
counter++;
}
}/// <summary>
/// Add update event
/// </summary>
/// <param name="stateName"> Status name </param>
/// <param name="updateEvent"> Update Events </param>
/// <param name="updateEventParamters"> Update the parameters used in the event execution </param>
public void AddUpdateEvent(string stateName, Action<object[]> updateEvent, object[] updateEventParamters) {
// If the state exists in the dictionary
if (StateUpdateModuleDic.ContainsKey(stateName))
{
// to update Update Events and parameters
StateUpdateModuleDic[stateName] = new StateUpdateModule(updateEvent, updateEventParamters);
}
else {
// add to Update Events and parameters
StateUpdateModuleDic.Add(stateName, new StateUpdateModule(updateEvent, updateEventParamters));
}
// Turn it upside down
DicToArray();
}
/// <summary>
/// Remove update event
/// </summary>
/// <param name="stateName"></param>
public void RemoveUpdateEvent(string stateName) {
if (StateUpdateModuleDic.ContainsKey(stateName)) {
// remove
StateUpdateModuleDic.Remove(stateName);
// Turn it upside down
DicToArray();
}}
/// <summary>
/// test
/// </summary>
/// <returns></returns>
private void Test1(object[] objs) {
Debug.Log("Test");
Debug.Log("Objs:"+objs.Length);
}
private void Test2(object[] objs)
{
Debug.Log("Test2" + objs.Length);
}
private IEnumerator Start()
{
//Test:
//AddUpdateEvent(stateName:"TestState",updateEvent:Test1,updateEventParamters:new object[] { 1,2,3});
//AddUpdateEvent(stateName: "NewTestState", updateEvent: Test2, updateEventParamters: new object[] { 4,5 });
while (true) {
if (invokeInterval <= 0)
{
// Wait a frame
yield return 0;}
else {
// Wait a time interval
yield return new WaitForSeconds(invokeInterval);
}
Execution event
for (int i = 0; i < stateUpdateModuleArray.Length; i++) {
if (stateUpdateModuleArray[i].stateUpdateEvent != null) {
// Call each event in the array , And pass the parameters
stateUpdateModuleArray[i].stateUpdateEvent(stateUpdateModuleArray[i].stateUpdateEventParamters);
}
}
//foreach (KeyValuePair<string,StateUpdateModule> updateModule in StateUpdateModuleDic)
//{
// if (updateModule.Value.stateUpdateEvent != null) {
// // Call each event in the dictionary , And pass the parameters
// updateModule.Value.stateUpdateEvent(updateModule.Value.stateUpdateEventParamters);
// }
//}
}
}}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace FSMFrame
{
public class StateMachine : State
{
#region Manager States
/// <summary>
/// The state of being managed
/// </summary>
private Dictionary<string, State> manageredStates;
/// <summary>
/// Default state
/// </summary>
private State defaultState;
/// <summary>
/// current state
/// </summary>
private State currentState;
public StateMachine(string name) : base(name)
{
manageredStates = new Dictionary<string, State>();
// Bind initial event
StateMachineEventBind();
}private void StateMachineEventBind() {
OnStateUpdate += CheckCurrentSTateTransition;
}
/// <summary>
/// Add state
/// </summary>
/// <param name="stateName"></param>
/// // Add... By status name
public State AddState(string stateName) {
if (IsRun)
{
Debug.LogWarning(" The status has been started , Status deletion is not allowed ");
return null;
}
if (manageredStates.ContainsKey(stateName))
{
Debug.LogWarning(" The state already exists ");
return manageredStates[stateName];
}
// Create a state of
State crtState = new State(stateName);
// Add state
manageredStates.Add(stateName, crtState);
// The currently added state is the first state
if (manageredStates.Count == 1) {
// The current state is the default state
defaultState = crtState;
}
return crtState;
}
/// <summary>
/// Add state
/// </summary>
/// <param name="crtState"></param>
public void AddState(State crtState) {
if (manageredStates.ContainsKey(crtState.StateName))
{
Debug.LogWarning(" The state already exists ");
return;
}
// Add state
manageredStates.Add(crtState.StateName, crtState);
// The currently added state is the first state
if (manageredStates.Count == 1)
{
// The current state is the default state
defaultState = crtState;
}
}
/// <summary>
/// Remove state
/// </summary>
/// <param name="stateName"></param>
public void RemoveState(string stateName) {
if (IsRun)
{
Debug.LogWarning(" The status has been started , Status deletion is not allowed ");
return;
}
// If the current state is in the state machine , And not the current state
if (manageredStates.ContainsKey(stateName)&&manageredStates[stateName]!=currentState) {
// Current status to delete
State crtState = manageredStates[stateName];
// Remove state
manageredStates.Remove(stateName);
// If the current state is the default state
if (manageredStates[stateName] == defaultState) {
// Clear the last default state
defaultState = null;
// Select the new default state
ChooseNewDefaultState();
}
}
}
/// <summary>
/// Select the new default state
/// </summary>
private void ChooseNewDefaultState() {
foreach (KeyValuePair<string,State> item in manageredStates) {
// Traverse to the first state set to the default state
defaultState = item.Value;
return;
}
}
#endregion#region State Machine Event
/// <summary>
/// The entry of the state machine
/// </summary>
/// <param name="enterEventparamters"></param>
/// <param name="updateEventParamters"></param>
public override void EnterState(object[] enterEventparamters, object[] updateEventParamters)
{
// First execute the entry event of the current state machine
base.EnterState(enterEventparamters, updateEventParamters);
// When executing the entry of sub state
// Determine whether there is a default state
if (defaultState == null) {
return;
}
// At this time, the current state is the default state
currentState = defaultState;
// Current state execution entry event [ Enter the default sub state ]
currentState.EnterState(enterEventparamters, updateEventParamters);
}
/// <summary>
/// The departure of the state machine
/// </summary>
/// <param name="paramters"></param>
public override void ExitState(object[] paramters)
{ // If the status is not empty
if (currentState != null)
{
// Leave the current status first
currentState.ExitState(paramters);
}
// The state machine leaves
base.ExitState(paramters);
}
#endregion#region State Machine Check State Transition
/// <summary>
/// Check whether the current state meets the transition conditions , Meet and transition
/// </summary>
private void CheckCurrentSTateTransition(object[] objs) {
// Detect transition events
string targetState=currentState.CheckTransition();
// When the current state reaches the transition event, it meets
if (targetState != null) {
// Transition to a new state
TransitionToState(targetState);
}
}private void TransitionToState(string targetStateName) {
// Whether the state to be transitioned is managed by the current state machine
if (manageredStates.ContainsKey(targetStateName)) {
// The current status leaves
currentState.ExitState(null);
// Switch the current state to the new state
currentState = manageredStates[targetStateName];
// The new current state execution enters
currentState.EnterState(null, null);
}
}
#endregion
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using FSMFrame;public class UseFSM : MonoBehaviour {
/// <summary>
/// Total state machine
/// </summary>
private StateMachine leader;
[Range(0,10)]
[Header(" Speed parameters ")]
public float speed;
private void Start()
{
// Instantiation
leader = new StateMachine("leader");
// Create sub state
State idleState = new State("Idle");
State walkState = new State("Walk");
State runState = new State("Run");
// Create a sub state machine
StateMachine locomotionState = new StateMachine("Locomotion");
// Establish state relationships
locomotionState.AddState(walkState);
locomotionState.AddState(runState);
leader.AddState(idleState);
leader.AddState(locomotionState);
// Add status event
leader.OnStateEnter += objects => { Debug.Log("Leader Enter!"); };
leader.OnStateUpdate += objects => { Debug.Log("Leader Update!"); };
leader.OnStateExit += objects => { Debug.Log("Leader Exit!"); };locomotionState.OnStateEnter += objects => { Debug.Log("locomotionState Enter!"); };
locomotionState.OnStateUpdate += objects => { Debug.Log("locomotionState Update!"); };
locomotionState.OnStateExit += objects => { Debug.Log("locomotionState Exit!"); };idleState.OnStateEnter += objects => { Debug.Log("idleState Enter!"); };
idleState.OnStateUpdate += objects => { Debug.Log("idleState Update!"); };
idleState.OnStateExit += objects => { Debug.Log("idleState Exit!"); };walkState.OnStateEnter += objects => { Debug.Log("walkState Enter!"); };
walkState.OnStateUpdate += objects => { Debug.Log("walkState Update!"); };
walkState.OnStateExit += objects => { Debug.Log("walkState Exit!"); };runState.OnStateEnter += objects => { Debug.Log("runState Enter!"); };
runState.OnStateUpdate += objects => { Debug.Log("runState Update!"); };
runState.OnStateExit += objects => { Debug.Log("runState Exit!"); };// Add state transition relationship
idleState.RegisterTransitionState("Locomotion", () => {return speed > 1; });
locomotionState.RegisterTransitionState("Idle", () => { return speed <= 1; });
walkState.RegisterTransitionState("Run", () => { return speed > 5;});
runState.RegisterTransitionState("Walk",()=> { return speed <= 5; });// Start state machine
leader.EnterState(null, null);
}
}
边栏推荐
- The new retail market has set off blind box e-commerce. Can the new blind box marketing model bring dividends to businesses?
- Interface oriented programming in C language
- 【微弱瞬态信号检测】混沌背景下微弱瞬态信号的SVM检测方法的matlab仿真
- Unable to find method 'org gradle. api. artifacts. result. ComponentSelectionReason. getDesc
- C # mapping from entity class to database (SQLite)
- Periodontitis investigation (ongoing)
- 上位机开发(固件下载软件之编码调试)
- How to make a development board from scratch? Illustrated and illustrated, step by step operation for you to see.
- JS method of extracting numbers from strings
- 学习Mysql基础第一天
猜你喜欢

Intelligent entertainment has developed steadily, and jinglianwen technology provides data collection and labeling services

Common method of props changing value V-model sync

What is the essence of social e-commerce disruption? How can businesses get more traffic?

Do you want to carry out rapid steel mesh design and ensure the quality of steel mesh? Look here

Br tool backup recovery

The causes of font and style enlargement when the applet is horizontal have been solved

数字时代进化论
![[cloud native | kubernetes] kubernetes configuration](/img/cb/20595d34a9e203b83dd086cc27037d.png)
[cloud native | kubernetes] kubernetes configuration

学习Mysql基础第一天

不间断管理设计
随机推荐
Gold jewelry enterprise operation mode, beautiful tiantians business solution
Differences between SQL and NoSQL of mongodb series
ML:机器学习模型的稳定性分析简介、常见的解决方法之详细攻略
在 localStorage 中上传和检索存储图像
JS method of extracting numbers from strings
景联文科技提供一站式智能家居数据采集标注解决方案
智能文娱稳步发展,景联文科技提供数据采集标注服务
Recently, the popular social e-commerce marketing model, blind box e-commerce, how beautiful every second is accurately drained
JS case Xiaomi second kill countdown New Year Countdown
FSM状态机
What is the new business model of Taishan crowdfunding in 2022?
16、 IO stream (II)
Fe of mL: introduction to vintage curve /vintage analysis, calculation logic and detailed introduction to case application
Eureka server multi node deployment
In the era of membership based social e-commerce, how do businesses build their own private domain traffic pool?
【腾讯阿里最全面试题集锦】(四面:3轮技术+1轮HR)
Tidb dashboard modify port
Tidb grafana reverse proxy
Jinglianwen technology provides voice data acquisition and labeling services
DataGridView data export to excel (in case of small amount of data)