20250523-简易的状态机代码模板及分析

文章介绍了在Unity中使用C#创建的状态机类,如PlayerState、PlayerIdleState和PlayerMoveState,展示如何通过状态机控制玩家角色的不同行为状态,如Idle和Move,并通过Input.GetKeyDown事件进行状态切换。

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

20250523-简易的状态机代码模板及分析

前情提要,以下是个人对状态机的部分理解:

(1)状态机示例主要包括Player、PlayerStateMachine、PlayerState三部分;

(2)Player既作为小数据库(有点像单例模式的对象池),存储Player相关属性、创建全局唯一的状态对象和状态机对象;又通过继承MonoBehavior类,执行整个生命周期(Awake、Start、Update等),在各个生命周期函数中调用状态机对象;Player对象本身代表Unity悬挂脚本的组件;

(3)PlayerStateMachine为状态机对象,主要维护一个属性,即当前对象正处于哪个状态;主要有两个动作:一是状态初始化,一般只会有一次;二是当前状态的切换;

(4)PlayerState表示对象的一种状态(可继续细分),一般维护状态的某些信息,如状态名称等;还要获得Player对象和PlayerStateMachine对象用于在执行某些动作时方便调用,例如当Player对象的某个属性满足条件时,进行切换当前状态的操作。主要的动作有三个方面:一是进入状态是干什么;二是处于当前状态时需要一直重复干什么;三是退出当前状态是需要干什么(例如重置某些属性的数值等);


以下是代码:

PlayerState.cs

using System.Collections;
using System.Collections.Generic;
using Unity.VisualScripting;
using UnityEngine;

public class PlayerState
{
    protected PlayerStateMachine stateMachine;
    protected Player player;
    private string animBoolName;

    public PlayerState(PlayerStateMachine stateMachine, Player player, string animBoolName)
    {
        this.stateMachine = stateMachine;
        this.player = player;
        this.animBoolName = animBoolName;
    }

    public virtual void Enter()
    {
        Debug.Log("I enter " + animBoolName);
    }

    public virtual void Update()
    {
        Debug.Log("I'm in " + animBoolName);
    }

    public virtual void Exit()
    {
        Debug.Log("I exit " + animBoolName);
    }
}

PlayerIdleState.cs

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

public class PlayerIdleState : PlayerState
{
    public PlayerIdleState(PlayerStateMachine stateMachine, Player player, string animBoolName) : base(stateMachine, player, animBoolName)
    {
    }

    public override void Enter()
    {
        base.Enter();
    }

    public override void Exit()
    {
        base.Exit();
    }

    public override void Update()
    {
        base.Update();
        if (Input.GetKeyDown(KeyCode.N))
            stateMachine.ChangeState(player.moveState);

    }
}

PlayerMoveState.cs

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

public class PlayerMoveState : PlayerState
{
    public PlayerMoveState(PlayerStateMachine stateMachine, Player player, string animBoolName) : base(stateMachine, player, animBoolName)
    {
    }

    public override void Enter()
    {
        base.Enter();
    }

    public override void Exit()
    {
        base.Exit();
    }

    public override void Update()
    {
        base.Update();
        if (Input.GetKeyDown(KeyCode.N))
            stateMachine.ChangeState(player.idleState);
    }
}

PlayerStateMachine.cs

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

public class PlayerStateMachine
{
    public PlayerState currentState { get; private set; }

    public void Initiallize(PlayerState _startState)
    {
        currentState = _startState;
        currentState.Enter();
    }

    public void ChangeState(PlayerState _newState)
    {
        currentState.Exit();
        currentState = _newState;
        currentState.Enter();
    }

}

Player.cs

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

public class Player : MonoBehaviour
{
    public PlayerStateMachine stateMachine { get; private set; }
    
    public PlayerIdleState idleState { get; private set; }
    public PlayerMoveState moveState { get; private set; }

    private void Awake()
    {
        stateMachine = new PlayerStateMachine();

        idleState = new PlayerIdleState(stateMachine, this, "Idle");
        moveState = new PlayerMoveState(stateMachine, this, "Move");
    }
    private void Start()
    {
        stateMachine.Initiallize(idleState);
    }
    private void Update()
    {
        stateMachine.currentState.Update();
        
    }
}


在这里插入图片描述

希望本文对您有所帮助~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值