ステートマシンの設計と実装
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での設定
- シーンに空のGameObjectを作成し、"Player"と名付けます
- 作成したPlayer.csをアタッチします
- Animatorコンポーネントを追加します
- 適切なアニメーションコントローラーを設定します