1024programmer Asp.Net Unity advanced development-FSM finite state machine

Unity advanced development-FSM finite state machine

Unity advanced development-FSM finite state machine

# Unity advanced development-FSM finite state machine

Foreword

When we develop, to a certain extent, we will encounter dozens of states. If we continue to use Unity’s Animator controller, a large number of bool and float type variables will appear, and these intricate variables are just like the Animatator controller. The combination of maze version connections will become extremely complex and cannot be well maintained and expanded. The emergence of a BUG will cause developers to bear great mental strength during the development process. At this time, using finite state machines or AI behavior trees becomes An excellent choice, This article only records the development of finite state machines

Using finite state machines for state management and switching can greatly reduce the difficulty of development. During the development process, you only need to pay attention to the switching between each state

Illustration of FSM working process:

We can see that the FSM script is divided into two large parts, one of which is inherited from IState, which stores the behaviors executed in the state, such as entering the state, leaving the state, and logical switching (used to determine whether to switch to other states), PlayerState implements this interface and inherits the ScriptableObject class. When we see ScriptableObject, we know the role of PlayerState. The objects of the ScriptableObject class do not depend on the objects in the scene, but are independent data files. Here, PlayState saves the behavioral logic functions of the state. The essential function of these behavioral logic functions is to execute relevant behaviors when conditions are met. Of course, use an example in FSM to illustrate that when the player is in the running state, the PlayState file finds that the logic for executing the running behavior is met, and the running animation needs to be played. We know that the data of ScriptableObject will not change by itself, so all judgment logic can only be used once. How should we solve this problem? This requires the class of the second section of FSM to implement it

It is not difficult to find that StateMachine inherits MonoBehaviour, which needs to be mounted into the scene, and the Update function can also be used to change the detected information at any time. Then, as mentioned above, PlayerState data cannot Actively change, and the data of StateMachine can change, so we can use a function to detect the data in StateMachine and send it to PlayerState, so that the data files created by PlayerState can continuously make logical judgments

Okay, now start coding and continue talking using code

No.1 IState

public interface IState
 {
     //Enter state
     void Enter() { }
     //exit status
     void Exit() { }
     //Status logic update
     void LogicUpdate() { }
 }
 

Here is the behavior function that needs to be executed inside the state

No.2 StateMachine

// 
 /// Hold all status classes, manage and switch them
 /// Responsible for updating the current status
 /// 
 public class StateMachine : MonoBehaviour
 {
     IState currentState; //current state
     public Dictionary stateTable; //Dictionary, used to save state and query state, convenient for state switching //Search
     public void Update()
     {
         currentState.LogicUpdate(); //Execute the logical switching function of each state, which can enable the state to detect //Transform, similar to the function in Update that receives information in real time
     }
     //switch state
     protected void SwitchOn(IState newState)
     {
         //The current state changes to the new state
         currentState = newState;
         //Enter new state
         currentState.Enter();
     }
     //
     public void SwitchState(IState newState)
     {
         //exit status
         currentState.Exit();
         //Enter new state
         SwitchOn(newState);
     }
     //Switch state function overload
     public void SwitchState(System.Type newStateType)
     {
         SwitchState(stateTable[newStateType]); //Pass in the state in the dictionary
     }

 }
 

No.3 PlayetState

public class PlayerState : ScriptableObject, IState
 {
     /******************Physical Detection******************/
     protected bool isGround; //Whether it is on the ground
     /*************basic information*************/
     protected bool isRun; //Whether to run
     protected bool isJump; //Whether to jump
     protected bool isIdle; //Whether it is still
     /******************Related components****************/
     protected Rigidbody2D my_Body2D; //Rigid body component, used to obtain the rigid body properties of the objectEnter the state and play the Idle animation by default.
         animator.Play("PlayerJump");
     }
    
     //Logic switching function, when a certain state is detected, the data file in that state will be executed immediately
     //In this script, other actions cannot be performed after jumping. You can add judgment if necessary.
     public override void LogicUpdate()
     {
         if(my_Body2D.velocity.y<0&&!isGround)
         {
             stateMachine.SwitchState(stateMachine.stateTable[typeof(PlayerState_Fall)]);
         }
     }
 }
 

No.7 PlayerState_Fall

[CreateAssetMenu(menuName = "StateMachine/PlayerState/Fall", fileName = "PlayerState_Fall")]//Create file
 public class PlayerState_Jump : PlayerState
 {
     /************************Physical Detection************************/
     public override void Enter()
     {
         //Execute the state data file, first execute the entry state function, and then perform related behaviors in the entry state function
         //Enter the state and play the Fall animation by default
         animator.Play("PlayerFall");
     }
    
     //Logic switching function, when a certain state is detected, the data file in that state will be executed immediately
     //In this script, other actions cannot be performed when falling. You can add judgment if necessary.
     public override void LogicUpdate()
     {
         if(isGround)
         {//Enter Idle state after landing
             stateMachine.SwitchState(stateMachine.stateTable[typeof(PlayerState_Idle)]);
         }
     }
 }
 

No.8 PlayerState_Run

[CreateAssetMenu(menuName = "StateMachine/PlayerState/Run", fileName = "PlayerState_Run")]//Create file
 public class PlayerState_Idle : PlayerState
 {
     /************************Physical Detection************************/
     public override void Enter()
     {
         //Execute the state data file, first execute the entry state function, and then perform related behaviors in the entry state function
         //Enter the state and play the Run animation by default
         animator.Play("PlayerRun");
     }
    
     //Logic switching function, when a certain state is detected, the data file in that state will be executed immediately
     public override void LogicUpdate()
     {
         if(isIdle)
         {
             stateMachine.SwitchState(stateMachine.stateTable[typeof(PlayerState_Idle)]);
         }
         if(isJump)
         {
             stateMachine.SwitchState(stateMachine.stateTable[typeof(PlayerState_Jump)]);
         }
         if(my_Body2D.velocity.y<0&&!isGround)
         {
             stateMachine.SwitchState(stateMachine.stateTable[typeof(PlayerState_Fall)]);
         }
     }
 }
 

The above is a simple state machine

Summary and Extension

FSM can greatly reduce the judgment and switching between player animations. You only need to pay attention to the switching conditions from one state to another. If the conditions are met, switch, and if not, continue execution

The use of FSM on players is not obvious, because here, after entering a certain state, we only play animations and do not perform other actions. It will be more convenient when we use it in monster AI. For example, if the monster is in patrol state, play the patrol animation, and execute the patrol script file (create a class specifically to store the monster AI status behavior function, and pass the class to The object is passed to EnemyState, which is operated by EnemyState). The monster is in the state of chasing the player, plays the chasing animation, and executes the behavior function of chasing the player. In the monster AI, the application of FSM will make it easier to manage monsters, and monsters can use skills. Enter the skill state, and when a player is found, he will start chasing the player. One condition and one action are more conducive to FSM management

Supplement

The following is an EnemyAI structural diagram I wrote myself. This example is used to show the general application of FSM in monster AI (not the project version, just a rough representation)

This article is from the internet and does not represent1024programmerPosition, please indicate the source when reprinting:https://www.1024programmer.com/unity-advanced-development-fsm-finite-state-machine/

author: admin

Previous article
Next article

Leave a Reply

Your email address will not be published. Required fields are marked *

Contact Us

Contact us

181-3619-1160

Online consultation: QQ交谈

E-mail: [email protected]

Working hours: Monday to Friday, 9:00-17:30, holidays off

Follow wechat
Scan wechat and follow us

Scan wechat and follow us

Follow Weibo
Back to top
首页
微信
电话
搜索