Unityにおけるステートマシンの基礎構築

ステートマシンの設計と実装

2Dプラットフォーマー系ゲームにおける状態管理を目的に、Unityでステートマシンを構築する方法を解説します。この設計は、キャラクターの動作状態(例:アイドル、移動、攻撃)を効率的に管理するために有効です。

1. 状態基底クラスの作成

まず、すべての状態クラスが継承するベースクラスを定義します。このクラスには、状態遷移のための抽象メソッドが含まれます。

// BaseState.cs
using UnityEngine;

public abstract class BaseState
{
    protected PlayerStateMachine stateMachine;
    protected Player player;
    protected string animBool;

    protected BaseState(PlayerStateMachine stateMachine, Player player, string animBool)
    {
        this.stateMachine = stateMachine;
        this.player = player;
        this.animBool = animBool;
    }

    public abstract void Enter();
    public abstract void Update();
    public abstract void Exit();
}

2. ステートマシンクラスの実装

状態の管理と遷移を行うステートマシンクラスを実装します。現在の状態を保持し、状態の変更を安全に行います。

// PlayerStateMachine.cs
public class PlayerStateMachine
{
    public BaseState CurrentState { get; private set; }

    public void Initialize(BaseState initialState)
    {
        CurrentState = initialState;
        CurrentState.Enter();
    }

    public void TransitionTo(BaseState newState)
    {
        CurrentState.Exit();
        CurrentState = newState;
        CurrentState.Enter();
    }
}

3. 具体的な状態の実装

次に、2つの具体的な状態クラスを実装します。今回はアイドル状態と移動状態を作成します。

// IdleState.cs
public class IdleState : BaseState
{
    public IdleState(PlayerStateMachine stateMachine, Player player, string animBool) 
        : base(stateMachine, player, animBool)
    {
    }

    public override void Enter()
    {
        // アニメーションのブーリアンを設定
        player.Animator.SetBool(animBool, true);
    }

    public override void Update()
    {
        // 水平入力が検出されたら移動状態に遷移
        if (Input.GetAxisRaw("Horizontal") != 0)
        {
            stateMachine.TransitionTo(((Player)player).MoveState);
        }
    }

    public override void Exit()
    {
        player.Animator.SetBool(animBool, false);
    }
}
// MoveState.cs
public class MoveState : BaseState
{
    public MoveState(PlayerStateMachine stateMachine, Player player, string animBool) 
        : base(stateMachine, player, animBool)
    {
    }

    public override void Enter()
    {
        player.Animator.SetBool(animBool, true);
    }

    public override void Update()
    {
        // 入力が0になったらアイドル状態に戻る
        if (Input.GetAxisRaw("Horizontal") == 0)
        {
            stateMachine.TransitionTo(((Player)player).IdleState);
        }
    }

    public override void Exit()
    {
        player.Animator.SetBool(animBool, false);
    }
}

4. プレイヤークラスの実装

最後に、すべてを統合するプレイヤークラスを実装します。

// Player.cs
public class Player : MonoBehaviour
{
    public PlayerStateMachine StateMachine { get; private set; }
    public IdleState IdleState { get; private set; }
    public MoveState MoveState { get; private set; }
    public Animator Animator { get; private set; }

    private void Awake()
    {
        Animator = GetComponent<Animator>();
        StateMachine = new PlayerStateMachine();
        
        IdleState = new IdleState(StateMachine, this, "Idle");
        MoveState = new MoveState(StateMachine, this, "Move");
    }

    private void Start()
    {
        StateMachine.Initialize(IdleState);
    }

    private void Update()
    {
        StateMachine.CurrentState.Update();
    }
}

5. Unityでの設定

  1. シーンに空のGameObjectを作成し、"Player"と名付けます
  2. 作成したPlayer.csをアタッチします
  3. Animatorコンポーネントを追加します
  4. 適切なアニメーションコントローラーを設定します

タグ: Unity C# ステートマシン ゲーム開発 OOP

6月4日 17:44 投稿