从零开始的类银河恶魔城游戏01

[自学]从零开始的类银河恶魔城游戏01

### part 1:Setup Animator with State Machine 2024/12/4 ###

我们先从最基本的状态机开始(2种状态:idle和move)

//Player.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player: MonoBehaviour
{
    #region Components
    public Animator anim { get; private set; }
    #endregion
//分门别类
    #region States
    public PlayerStateMachine stateMachine { get; private set; }

    public PlayerIdleState idleState { get; private set; }
    public PlayerMoveState moveState { get; private set; }
    #endregion
//Awake函数用来定义状态机及各种状态
    private void Awake()
    {
        stateMachine = new PlayerStateMachine();

        idleState = new PlayerIdleState(this,stateMachine,"Idle");
        moveState = new PlayerMoveState(this,stateMachine,"Move");

    }
//Start函数用来定义初始状态idleState
    public void Start()
    {
        anim = GetComponentInChildren<Animator>();
        stateMachine.Initialize(idleState);// PlayerStateMachine.Initialize()
    }
//Update函数更新状态机
    public void Update()
    {
        stateMachine.currentState.Update();// PlayerState.Update()
    }

}
//PlayerStateMachine.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerStateMachine
{
    public PlayerState currentState { get; private set; }     //只读属性,仅获取当前状态

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

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

状态cs文件的编写步骤:

  1. alt+enter生成构造函数
    img

2.然后生成重写
img

3.只留下面三个函数即可,进入、更新、退出
img

//PlayerState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerState
{
    protected PlayerStateMachine stateMachine;
    protected Player player;

    private string animBoolName;

    public PlayerState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName)
    {
        this.player = _player;
        this.stateMachine = _stateMachine;
        this.animBoolName = _animBoolName;
    }
//进入某个状态置1
    public virtual void Enter()
    {
        player.anim.SetBool(animBoolName, true);
    }

    public virtual void Update()
    {
        Debug.Log("I'm in " + animBoolName);
    }
//退出当前状态置0
    public virtual void Exit()
    {
        player.anim.SetBool(animBoolName, false);
    }

}
//PlayerMoveState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMoveState : PlayerState
{
    public PlayerMoveState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
    {

    }

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

    public override void Exit()
    {
        base.Exit();
    }
//在Update里面定义状态切换的条件
    public override void Update()
    {
        base.Update();
        if (Input.GetKeyDown(KeyCode.N))
        {
            player.stateMachine.ChangeState(player.idleState);
        }
    }
}

//在“Player***State.cs”的Update里面定义状态切换的条件

//注意继承是PlayerState

//PlayerIdleState.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerIdleState : PlayerState
{
    public PlayerIdleState(Player _player, PlayerStateMachine _stateMachine, string _animBoolName) : base(_player, _stateMachine, _animBoolName)
    {

    }

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

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

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

参考教程:

The Ultimate Guide to Creating an RPG Game in Unity(Begin with StateMachine)

posted @ 2025-03-06 20:38  EanoJiang  阅读(28)  评论(0)    收藏  举报