Unityに関連する記事です

 前回に続いて、必殺技の機能について、抽象化を行って実装していく手法を学習します。

設計


 抽象化を行わない場合の必殺技の処理の作り方については、下記のような処理が一般的です。

1.enum で必殺技の種類を事前に列挙子として登録しておく(文字列で指定するよりも安全)
2.必殺技を使うタイミングで、switch 文(if 文)と列挙子を使って、どの必殺技であるかを特定する
3.特定した必殺技用のメソッドを用意しておいて、そのメソッドを実行する。

 上記の処理のサンプルコードとしては、次のようなものが考えられます。

using UnityEngine;

/// <summary>
/// 必殺技の種類
/// </summary>
public enum SpecialSkillType
{
    Fireball,
    LightningStrike,
    Tornado,
    // 他の必殺技を追加で列挙子として定義する
}

public class Player : MonoBehaviour
{
    // プレイヤーのステータスやその他のコンポーネントなど...

    // 必殺技を使うメソッド
    public void UseSpecialSkill(SpecialSkillType skillType)
    {
        switch (skillType)
        {
            case SpecialSkillType.Fireball:
                PerformFireball();
                break;
            case SpecialSkillType.LightningStrike:
                PerformLightningStrike();
                break;
            case SpecialSkillType.Tornado:
                PerformTornado();
                break;

            // 他の必殺技に対応する処理を追加する
            default:
                Debug.LogError("Unsupported Special Skill Type: " + SkillType);
                break;
        }
    }

    // 各必殺技用のメソッドを定義
    private void PerformFireball()
    {
        // Fireballの処理
        Debug.Log("Fireball!");
    }

    private void PerformLightningStrike()
    {
        // Lightning Strikeの処理
        Debug.Log("Lightning Strike!");
    }

    private void PerformTornado()
    {
        // Tornadoの処理
        Debug.Log("Tornado!");
    }
}

 この処理は問題なく動作します。

 ですが、必殺技の数が増減するたび、常にソースコードの修正が必要になります。
必殺技が増減するたびに、分岐処理である switch 文や列挙子への修正が必要になります。

 たくさんの必殺技が出てくるゲームにおいては、このような設計では必殺技の追加や修正がやりにくいですね。
また修正が多いということは、書き間違えが増える要因となり、確認作業も増えてしまうことから、全体的な作業効率も悪くなってしまいます。

 そこで今回実装している処理の抽象化の考え方と設計方法が解決策の1つとなります。



 抽象化の最も大きな違いは、分岐処理が一切なくなる点です。

 インターフェースを実装した親クラスである SpecialSkillBase クラスを利用し、
子クラスの特定は行わず、親クラスのみを判断し、処理を進めていくようにします。
このような形式にすることで、プログラムは子クラスがどのようなクラスであるかは知らない状態で、子クラスの処理を動かします。

 ポイントはこの部分です。
親クラスのみを判断の基準としつつ、実際に動いてるのは子クラスである、ということです。
 
 そして親クラスに用意してある仮想メソッドは子クラスによって上書きされていますので、
実際には、各子クラスのメソッドが実行されます。そこには、それぞれの必殺技の処理が書かれていますので、
仮想メソッドを実行すると、同じ親クラスを持つ子クラスでは処理が変わる仕組みです。

 このような機能を振る舞いを変えるといい、オブジェクト指向プログラミングにおける多態性の概念に当たります。


・SpecialSkillHandler   → 例えるなら、ゲーム機本体の役割。今回の必殺技(ゲームソフト)を登録し、電源を入れ、電源を落とす。必殺技の中身(ソフトの中身)までは管理しない。
・UIManager             → 必殺技専用の UI 制御クラス 
・SpecialSkillManager    → 上記の2つの制御を行う、必殺技の管理者

 上記のクラスにおいては、Handler クラスが抽象化における重要な役割を持っています。


Handler クラスを作成する


 抽象化によって処理を実行しているクラスです。

 先ほどの手順において、親クラスである SpecialSkillBase クラスを「必殺技」として認識させるようにする、と解説しました。
このクラスがこの処理を請け負っています。

 このクラスでは必殺技の実行処理がありますが、必殺技の分岐処理がありません
固有の必殺技(子クラス)であるかどうかを確認する方法ではなく、「必殺技であるか、どうか」で処理を動かすようにしています。
そのため、分岐処理がなくても、「必殺技」であることだけ分かれば、処理を実行していく作りになっています。

 この際には、親クラスの情報を使い、仮想メソッド(インターフェースで実装している2つのメソッド)を実行する設計になっているため、
「必殺技であるか、どうか」を判定したあとは、それが親クラスのメソッドなのか、子クラスのメソッドであるかに関わらず実行します。

 そして子クラスのメソッドを実行している場合には、上書きされている仮想メソッドの処理(それぞれの必殺技の処理)を実行しています。


<= クリックすると開きます


 このような設計にしておくことで、必殺技が増減しても、ソースコードへの修正は不要です。

 必殺技を増やす場合には新しい子クラスを作成します。
修正する場合にも、それぞれの子クラスの内容を修正します。

 抽象化することにより分岐処理がなくなっていますが、子クラスに書いてある必殺技が自動的に使い分けられる設計になっています。
 

UI 管理クラスを作成する


 必殺技の利用に関わる UI 部分の制御機能を管理するクラスです。

 ここではあくまでもサンプルです。
ボタンと必殺技用のゲージを管理していますが、必要に応じて、他にも追加・修正してください。


<= クリックすると開きます




Manager クラスを作成する


 必殺技に関連する処理をトータルで管理するクラスです。
Handler クラスと UIManager クラスを統括し、かつ、必殺技に必要な設定情報も管理しています。


<= クリックすると開きます



SpecialSkillManager ゲームオブジェクトを作成し、各スクリプトをアタッチする


 Create Empty で新規のゲームオブジェクトを作成し、この手順で作成した
Mangaer、Handler、UIManager をアタッチします。


 アサイン情報としては、UIManager のみ、UI 用のボタンやゲージ用の画像が参照として必要になります。

 それ以外は初期値で問題ありません。


インスペクター画像



ゲームを実行して動作を確認する


 デバッグ用に必殺技のポイントはボタンを押すことで加算できます。
この機能を利用して、必要なポイントが貯まったら必殺技のボタンが押せる状態になるか、確認しましょう。

 また必殺技のボタンを押したときに、指定している必殺技が実行されるかも確認してください。

 抽象化によって、親クラスにある共通の仮想メソッドが、上書きされた子クラスのメソッドの効果として実行されます。



 抽象化の処理は名前の通りでイメージがしにくく、理解することは簡単なことではありません。

 繰り返し処理を書いて実行し、どのような挙動になるのか、振る舞いを変えるとはどういうことなのかを体験して覚えていきましょう。

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

Menu



技術/知識(実装例)

2Dおはじきゲーム(発展編)

2D強制横スクロールアクション(発展編)

3Dダイビングアクション(発展編)

2Dタップシューティング(拡張編)

レースゲーム(抜粋)

2D放置ゲーム(発展編)

3Dレールガンシューティング(応用編)

3D脱出ゲーム(抜粋)

2Dリアルタイムストラテジー

2Dトップビューアドベンチャー(宴アセット使用)

3Dタップアクション(NavMeshAgent 使用)

2Dトップビューアクション(カエルの為に〜、ボコスカウォーズ風)

VideoPlayer イベント連動の実装例

VideoPlayer リスト内からムービー再生の実装例(発展)

AR 画像付きオブジェクト生成の実装例

AR リスト内から生成の実装例(発展)

private



このサイト内の作品はユニティちゃんライセンス条項の元に提供されています。

管理人/副管理人のみ編集できます