スポンサーリンク
UnityUnityメモ

【実践】UnityでRPGのスキルシステムを作る!ステートマシンで簡単管理

Unity

1. はじめに

RPGといえば、攻撃・回復・バフ・デバフなど多彩なスキルが登場しますよね。
プレイヤーにとってはバトルを盛り上げる要素ですが、開発者の視点では「どうやってスキルを実装するか」が大きな課題になります。

スキルの発動条件、効果の処理、クールダウン管理……これらをコードに直接書き込んでしまうと、だんだん複雑になって管理が大変に。新しいスキルを追加するたびに修正が必要になり、バグも増えやすくなります。

そこで活躍するのがステートマシン(状態遷移の仕組み)です。キャラクターやスキルを「待機」「発動」「クールダウン」といった状態ごとに分けて制御することで、処理の流れがすっきり整理され、拡張性の高い設計が可能になります。

この記事では、Unityを使ったRPGのスキルシステム構築方法を、初心者の方でも理解しやすい形で解説します。さらに、データ管理を楽にするScriptableObjectや、高性能な状態管理を実現するImtStateMachineについても触れていきます。

それでは早速、スキルシステムの基本設計から見ていきましょう!




2. スキルシステムの基本設計

RPGのスキルは大きく分けるとアクティブスキルパッシブスキルの2種類があります。どちらもゲーム性を大きく左右するため、設計段階でしっかり区別しておくことが大切です。

2-1. スキルの種類

  • アクティブスキル:プレイヤーの操作で発動するスキル。攻撃や回復、バフ・デバフなどが該当します。アニメーションやエフェクトと連携するため、ステートマシンでの管理が効果的です。
  • パッシブスキル:自動的に効果を発揮するスキル。ステータス上昇や特殊効果など、条件によって常に発動・適用されるタイプです。

2-2. スキル発動の基本フロー

スキルを実行する流れは、以下のように整理できます。

  1. 入力(Input):プレイヤーがボタンを押す、またはAIが条件を満たす
  2. 条件チェック:MPやスタミナの残量、クールダウンが終わっているか、敵との距離が適切かを確認
  3. 発動(Casting):アニメーションやダメージ計算、エフェクト再生を処理
  4. クールダウン:一定時間スキルを使用できないようにし、UIに残り時間を表示する

2-3. データ管理にScriptableObjectを使う

スキルの効果やクールダウンなどをすべてコードに直接書き込むと、あとで修正が大変になってしまいます。そこで役立つのがScriptableObjectです。スキルの名前・威力・クールダウン時間などをInspectorから簡単に編集でき、コードを書き換えずに新しいスキルを追加できます。

例えば「SkillData」というクラスを作り、ScriptableObjectを継承させてスキル名・威力・クールダウンをプロパティとして持たせます。
これをプロジェクトウィンドウで生成しておけば、スキル追加がとてもスムーズになります。

RPGシステムを一から組むのが大変な場合は、あらかじめスキルやクエスト、アイテム管理の仕組みが揃っているアセットを活用するのもおすすめです。
2D RPG Kit を使えば、実際のプロジェクトにすぐ取り入れられます。

ここまでで、スキルシステムを設計するための基盤が整いました。次は、実際にステートマシンを使ってスキルの状態管理を実装していきましょう。


3. スキルの状態管理と実装

スキルを整理するうえで欠かせないのが状態管理です。シンプルに考えるなら、スキルは以下の3つの状態に分類できます。

  • Ready(準備完了):いつでも発動できる状態
  • Casting(発動中):アニメーションやエフェクトが再生されている状態
  • Cooldown(クールダウン中):一定時間再使用できない状態

3-1. 状態をenumで定義する

まずはスクリプトで状態を表現するために列挙型を定義します。


public enum SkillState 
{ 
    Ready, 
    Casting, 
    Cooldown 
}

3-2. スキル管理用スクリプトの作成

次に「SkillSystem」というC#スクリプトを作成し、現在の状態とクールダウン用のタイマーを管理します。
Update()メソッドで状態に応じた処理を分岐させるのがポイントです。


public class SkillSystem : MonoBehaviour
{
    public SkillState state = SkillState.Ready;
    public float cooldownTimer = 0f;
    public SkillData skillData;

    void Update()
    {
        switch (state)
        {
            case SkillState.Ready:
                if (Input.GetKeyDown(KeyCode.Space))
                {
                    StartCoroutine(CastSkill());
                }
                break;

            case SkillState.Cooldown:
                cooldownTimer -= Time.deltaTime;
                if (cooldownTimer <= 0f)
                {
                    state = SkillState.Ready;
                }
                break;
        }
    }

    private IEnumerator CastSkill()
    {
        state = SkillState.Casting;
        Debug.Log("スキル発動!");

        // ダメージ処理やアニメーションを入れる
        yield return new WaitForSeconds(1.5f);

        state = SkillState.Cooldown;
        cooldownTimer = skillData.cooldown;
    }
}

3-3. 実装のポイント

  • 「Ready」ではキー入力を受け付け、スキルを発動する
  • 「Casting」ではアニメーションやダメージ処理を行い、演出が終了したらクールダウンへ移行する
  • 「Cooldown」ではタイマーを減らし、0になれば「Ready」に戻す

このように状態を明確に区切ることで、スキルごとの処理をシンプルに整理できます。
さらに理解を深めたい方には、C#とUnityを体系的に学べるこちらの書籍がおすすめです。


4. 視覚効果・演出の追加

スキルは単にダメージを与えるだけでは味気ないですよね。
迫力あるエフェクトやサウンドを加えることで、プレイヤーが「気持ちいい!」と感じる戦闘演出に仕上げることができます。

4-1. エフェクトの追加

UnityのParticle Systemを使えば、炎や氷、光の魔法陣などを簡単に作れます。
例えば「skillEffect」というパーティクルを用意して、スクリプトから以下のように呼び出します。


public ParticleSystem skillEffect;

private IEnumerator CastSkill()
{
    state = SkillState.Casting;
    skillEffect.Play(); // パーティクル再生
    Debug.Log("スキル発動演出!");

    yield return new WaitForSeconds(1.5f);

    state = SkillState.Cooldown;
    cooldownTimer = skillData.cooldown;
}

さらに、Shaderを使って武器に光のエフェクトを付与したり、発光(Emission)を強調すれば「特別な技」を表現できます。

4-2. アニメーションと連携

キャラクターの動きを演出するには、Animatorが欠かせません。
スキル発動時に「CastSkill」というトリガーを設定し、Animator Controllerで専用のアニメーションを再生させましょう。


public Animator animator;

private IEnumerator CastSkill()
{
    state = SkillState.Casting;
    animator.SetTrigger("CastSkill"); // 発動モーション
    yield return new WaitForSeconds(1.5f);

    state = SkillState.Cooldown;
    cooldownTimer = skillData.cooldown;
}

4-3. サウンドで臨場感をプラス

スキルにはAudioSourceを追加して、専用の効果音を流すとより臨場感が出ます。


public AudioSource skillSound;

private IEnumerator CastSkill()
{
    state = SkillState.Casting;
    skillSound.Play(); // スキル効果音
    yield return new WaitForSeconds(1.5f);

    state = SkillState.Cooldown;
    cooldownTimer = skillData.cooldown;
}

ビジュアル・アニメーション・サウンドを組み合わせれば、シンプルなスキルでもまるで本格的なRPGのように演出できます。

こうした演出を一から作るのは時間がかかるので、効率よく進めたい方は完成度の高いテンプレートやエフェクト素材を利用するのもおすすめです。
RPG Maker Unite には多彩な演出要素が揃っているので、開発スピードをぐっと上げられます。

次は、スキルをさらに応用して複数スキルやAIへの適用について解説していきましょう。


5. 応用:複数スキルとAIへの適用

基本的なスキルシステムができたら、次は複数スキルの管理AIキャラクターへの適用に挑戦してみましょう。これによってゲーム全体の戦略性や遊びごたえが一気に広がります。

5-1. スキルツリーの設計

プレイヤーが自由に成長できる仕組みを作るには、スキルツリーが有効です。代表的な設計方法は次の2つです。

  • スキルポイント制:レベルアップ時にポイントを獲得し、好きなスキルに割り振る方式
  • スキルレベル制:スキルを使うほど経験値がたまり、威力や効果が強化されていく方式

どちらの仕組みも、ScriptableObjectでスキルデータを持たせれば拡張しやすく、UIと連動させることでわかりやすい成長システムを実現できます。

5-2. AIキャラクターへの適用

スキルはプレイヤーだけでなく、敵やNPCに使わせることでバトルがより白熱します。
例えば、敵キャラにNavMeshAgentを使って移動させ、プレイヤーが一定距離に入ったらスキルを発動するようにすれば、シンプルなAIスキル攻撃が完成します。


if (Vector3.Distance(player.position, transform.position) <= attackRange)
{
    if (state == SkillState.Ready)
    {
        StartCoroutine(CastSkill());
    }
}

5-3. バランス調整のポイント

複数スキルを導入すると、どうしても「強すぎるスキル」や「ほとんど使われないスキル」が出てきます。
クールダウン時間、消費MP、ダメージ倍率を調整し、テストプレイを重ねながらゲームバランスを整えましょう。

5-4. アセットを活用した効率化

大規模なRPGシステムを効率よく作りたいなら、スキルやクエスト管理の機能が一式揃ったアセットを導入するのが近道です。
特におすすめなのがこちら:

  • RPG Maker Unite :本格的なRPG制作をトータルでサポート
  • 2D RPG Kit :2DベースのRPGテンプレート。初心者でも扱いやすい

6. ImtStateMachineの活用

ここまで紹介してきたスキルシステムはシンプルな状態管理で動作しますが、より複雑なゲームでは高度なステートマシンが必要になる場面があります。
そこで便利なのが、C#で実装された高性能な状態制御ライブラリImtStateMachineです。

6-1. 特徴

  • 軽量・高速:ナノ秒単位で動作し、GC Allocが発生しないためパフォーマンスに優れる
  • 安全性:UnhandledException機構によりエラー発生時も安定して動作
  • 柔軟性:どの型に対しても適用可能な「コンテキストフリー」な設計
  • 拡張機能:任意状態遷移、状態割り込み、遷移ガードなど高度な制御が可能

6-2. 基本的な使い方

ImtStateMachineでは、各状態をStateクラスとして定義し、Enter()Update()Exit()などのライフサイクルを実装します。
遷移はイベントIDを用いて管理され、SendEvent()を呼ぶことで状態を切り替えられます。


// コンテキストとなるクラス
public class Player { public int hp; }

// 状態クラスの定義
public class IdleState : ImtStateMachine<Player>.State
{
    protected override void Enter() { Debug.Log("待機状態"); }
    protected override void Update() 
    { 
        if (Context.hp <= 0) 
            StateMachine.SendEvent(1); // HP0で死亡イベント
    }
}

// 遷移テーブルの作成
var player = new Player();
var stateMachine = new ImtStateMachine<Player>(player);
stateMachine.AddTransition<IdleState, DeadState>(1);
stateMachine.SetStartState<IdleState>();

6-3. Unityでの利用例

ImtStateMachineはUnityのUpdate()FixedUpdate()から呼び出せるため、プレイヤーの状態や敵AIの制御にも最適です。
たとえば「通常攻撃」「スキル発動」「死亡」の状態を分け、条件に応じてスムーズに切り替えることができます。

6-4. 導入のメリット

自作のステートマシンよりも堅牢かつ高機能なので、大規模なRPGやオンラインゲームでも安心して利用できます。

スキル管理だけでなく、ゲーム進行やUI制御など幅広い用途で活用できるのも強みです。


7. まとめ

今回はUnityでRPGのスキルシステムを作る方法を、ステートマシンを中心に解説しました。
スキルの「準備 → 発動 → クールダウン」という流れを状態ごとに管理することで、コードをシンプルに保ちつつ拡張性の高い設計が可能になります。

  • スキルはアクティブスキルパッシブスキルに分類できる
  • ScriptableObjectを使えば、スキルデータを効率的に管理できる
  • ステートマシンを導入すると、複雑な処理を整理しやすくなる
  • ImtStateMachineを使えば、大規模なゲームでも柔軟かつ高速な状態管理が可能

スキルの演出を強化するなら、Particle SystemAnimatorAudioSourceを組み合わせるのが効果的です。これにより、プレイヤーに「爽快感のある戦闘体験」を提供できます。

さらに体系的にUnity開発を学びたい方にはこちらの書籍もおすすめです。

スキルシステムはRPGの肝となる部分です。この記事を参考に、ぜひ自分のゲームに合った仕組みを作ってみてくださいね!


あわせて読みたい

スキルシステムを学んだら、関連する記事もあわせてチェックすると理解が深まります。特に以下の記事はおすすめです。


よくある質問(FAQ)

Q
ScriptableObjectを使うメリットは?
A

スキルの威力やクールダウンなどのデータをInspectorから簡単に編集でき、コードを変更せずに新しいスキルを追加できます。
デザイナーやプランナーが直接値を調整できるのも大きなメリットです。

Q
ステートマシンを導入しないとどうなる?
A

スキルごとの条件分岐が増えて処理が複雑になり、修正や拡張が難しくなります。
「スキルを増やしたらバグが出た…」といったトラブルを避けるためにも、ステートマシンによる整理は有効です。

Q
初心者でもスキルシステムを作れる?
A

はい、基本的な流れ(準備 → 発動 → クールダウン)を理解すれば、誰でもシンプルなスキルシステムを作れます。
最初は攻撃スキルなど簡単なものから始め、少しずつパッシブスキルやAIへの応用に挑戦すると良いでしょう。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク