游戏简单控制逻辑 一个轻量级的状态机

本文介绍了一种轻量级的状态机实现方式,并通过Unity中的一个立方体状态切换实例进行演示。该状态机使用C#编写,适用于需要简单状态管理和过渡的游戏或应用程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

出处:http://blog.youkuaiyun.com/u010019717

author:孙广东      时间:2015.3.25 

 关于状态机这种设计模式不用多介绍了,网上有很多这方面的介绍,特别是FSM。

现在是我实现一个轻量级的状态机。

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3.   
  4. namespace Gamelogic  
  5. {  
  6.     /** 
  7.     一个轻量级的状态机。 
  8.     要使用它: 
  9.     -# 定义您自己的label。枚举Enums可能是最好的选择。 
  10.     -# 构造一个新的状态机state machin,通常是在 MonoBehaviour 的Start方法中。 
  11.     -# 添加的各种状态和对应的delegates。 
  12.     -# 从 MonoBehaviour 的Update方法调用状态机Update方法。 
  13.     -# 在状态机transition转换状态时调用 ChangeState 方法(你可以调用此方法,从一个state delegates,或任何其他地方) 
  14.     -# 状态发生变化时,对现有状态执行关闭 OnStop,然后OnStart开启新状态,之后新的状态每帧更新中调用 OnUpdate 方法 
  15.     */  
  16.     public sealed class StateMachine<TLabel>  
  17.     {  
  18.         private class State  
  19.         {  
  20.             public readonly Action onStart;  
  21.             public readonly Action onUpdate;  
  22.             public readonly Action onStop;  
  23.             public readonly TLabel label;  
  24.   
  25.             public State(TLabel label, Action onStart, Action onUpdate, Action onStop)  
  26.             {  
  27.                 this.onStart = onStart;  
  28.                 this.onUpdate = onUpdate;  
  29.                 this.onStop = onStop;  
  30.                 this.label = label;  
  31.             }  
  32.         }  
  33.   
  34.         private readonly Dictionary<TLabel, State> stateDictionary;  
  35.         private State currentState;  
  36.   
  37.         /** 
  38.             Returns the label of the current state. 
  39.         */  
  40.   
  41.         public TLabel CurrentState  
  42.         {  
  43.             get { return currentState.label; }  
  44.   
  45.             /**@version1_2*/  
  46.             set { ChangeState(value); }  
  47.         }  
  48.   
  49.         /** 
  50.             Constructs a new StateMachine. 
  51.         */  
  52.   
  53.         public StateMachine()  
  54.         {  
  55.             stateDictionary = new Dictionary<TLabel, State>();  
  56.         }  
  57.   
  58.         /** 
  59.             Adds a state, and the delegates that should run  
  60.             when the state starts, stops,  
  61.             and when the state machine is updated. 
  62.  
  63.             Any delegate can be null, and wont be executed. 
  64.         */  
  65.         public void AddState(TLabel label, Action onStart, Action onUpdate, Action onStop)  
  66.         {  
  67.             stateDictionary[label] = new State(label, onStart, onUpdate, onStop);  
  68.         }  
  69.   
  70.         /** 
  71.             Changes the state from the existing one to the state with the given label. 
  72.         */  
  73.         private void ChangeState(TLabel newState)  
  74.         {  
  75.             if (currentState != null && currentState.onStop != null)  
  76.             {  
  77.                 currentState.onStop();  
  78.             }  
  79.   
  80.             currentState = stateDictionary[newState];  
  81.   
  82.             if (currentState.onStart != null)  
  83.             {  
  84.                 currentState.onStart();  
  85.             }  
  86.         }  
  87.   
  88.         /** 
  89.             This method should be called every frame.  
  90.         */  
  91.         public void Update()  
  92.         {  
  93.             if (currentState != null && currentState.onUpdate != null)  
  94.             {  
  95.                 currentState.onUpdate();  
  96.             }  
  97.         }  
  98.     }  
  99. }  


使用的例子 很简单,cube的两种状态转换。 每种状态有不同的行为表现:

     

[csharp]  view plain copy print ? 在CODE上查看代码片 派生到我的代码片
  1. using System.Collections;  
  2. using UnityEngine;  
  3.   
  4. namespace Gamelogic.Examples  
  5. {  
  6.     public class Cube : MonoBehaviour   
  7.     {  
  8.   
  9.         public enum CubeStates   
  10.         {  
  11.             Swivel,  
  12.             MoveStraight  
  13.         }  
  14.   
  15.         private StateMachine<CubeStates> stateMachine;  
  16.         private float moveSpeed = 1;  
  17.         private float switchTime = 3;   
  18.         private float swivelSpeed = 2;  
  19.   
  20.         public void Start()  
  21.         {  
  22.             stateMachine = new StateMachine<CubeStates>();  
  23.   
  24.             stateMachine.AddState(CubeStates.Swivel, OnSwivelStart, OnSwivelUpdate, OnSwivelStop);  
  25.             stateMachine.AddState(CubeStates.MoveStraight, null, OnMoveStraightUpdate, null);  
  26.   
  27.             stateMachine.CurrentState = CubeStates.MoveStraight;  
  28.   
  29.             StartCoroutine(SwitchStates());  
  30.         }  
  31.   
  32.         public IEnumerator SwitchStates()  
  33.         {  
  34.             while (true)  
  35.             {  
  36.                 stateMachine.CurrentState = CubeStates.Swivel;  
  37.                 yield return new WaitForSeconds(switchTime);  
  38.   
  39.                 stateMachine.CurrentState = CubeStates.MoveStraight;  
  40.                 yield return new WaitForSeconds(switchTime);  
  41.             }  
  42.         }  
  43.   
  44.         public void Update()  
  45.         {  
  46.             stateMachine.Update();  
  47.         }  
  48.   
  49.         public void OnGUI()  
  50.         {  
  51.             GUILayout.TextField(stateMachine.CurrentState.ToString());  
  52.         }  
  53.   
  54.         public void OnMoveStraightUpdate()  
  55.         {  
  56.             float dx = -Time.deltaTime * moveSpeed;  
  57.   
  58.             transform.TranslateX(dx);  
  59.         }  
  60.   
  61.         public void OnSwivelUpdate()  
  62.         {  
  63.             float dx = Time.deltaTime*moveSpeed;  
  64.             float y = Mathf.Sin(swivelSpeed * transform.position.x * 2 * Mathf.PI/switchTime);  
  65.   
  66.             transform.TranslateX(dx);  
  67.             transform.SetY(y);  
  68.         }  
  69.   
  70.         public void OnSwivelStart()  
  71.         {  
  72.             GetComponent<Renderer>().material.color = Color.red;  
  73.         }  
  74.   
  75.         public void OnSwivelStop()  
  76.         {  
  77.             GetComponent<Renderer>().material.color = Color.green;  
  78.             transform.SetY(0); //recallibrate  
  79.         }  
  80.     }  
  81. }  

就是这样的很简单的状态机。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值