Unityに関連する記事です

アイテムを設計する


 アクションゲームだけに限らず、駆け引きを左右するようなパワーアップアイテムがランダムで出現したり、宝箱のようなボーナスアイテムが出現したりすると
ゲームのデザインが奥深くなります。
 
 一口にアイテムといっても様々な種類があると思いますので、まずはどのようなアイテムで、どのような意図があるのかを考えて
どのようにしたら出現するかなど、必要となる情報を元に設計を考えていきます。

 今回は、以下のようなアイテムを設計するようにします。

 ・敵を倒すことで、一定の確率で出現する。出現確率については敵側で設定できる。
 ・プレイヤーがアイテムに接触することで取得できる。
 ・敵はアイテムに接触しても取得できない。
 ・取得するとHPが回復する。回復値は割合ではなく実数値で、アイテム側で設定できる。
 ・出現している時間に制限はない。(取得するまで出現している。)
 これらの設計を踏まえて、プログラムを考えていきます。


1.クラスの継承を考えながら設計する


 今回のアイテムは回復効果を持つアイテムですが、今後、その種類を増やす場合を考えて、アイテム全体で共通して使用する変数や関数については
親クラスを用意して、そちらに記述していくことを念頭に置いておきます。アイテムを取得する処理、アイテムを削除する処理、というのは共通の処理になるでしょう。

 このような設計にしておくことにより、親クラスを継承した子クラスでは、例えば、回復アイテムであれば、回復の処理のみを記述することで
あとは親クラスの情報を継承するだけで作成が可能になります。なぜなら、アイテムを取得・削除する処理は親クラスに記載されているので、子クラスはその部分を省くことが出来るからです。

 またこのようなクラスの作りにしておくことで新たなアイテムを製作する場合にも、子クラスのみにそのアイテム独自の処理のみを実装すればよいことになります。
クラスを継承しない場合だと各アイテムのクラス内にすべての処理を記述しなければなり、非常に冗長な処理を何度となく書いていくことになってしまい手間だけが増えてしまいます。

 とはいえ、まずは親クラスではなく、1つのクラス内にすべての処理を書いてみましょう。その中で、これはアイテムという処理においては
共通化できる処理になりそうだという部分が見えてきますので、その後、親クラスと子クラスに切り分けて処理を書き換えていくようにしましょう。

 作成していく手順ですが、以下の順番になります。

 1.回復アイテム用クラスを設計して作成する
 2.回復アイテム用ゲームオブジェクトを作成してプレファブ化する
 3.回復アイテムを一定確率で生成するようにする(敵を倒した場合)
 4.プレイヤーが回復アイテムを取得できるようにし、HPが回復する処理を行う

 上記の順番で作っていきます。


2.回復アイテム用のクラスを設計して作成する


 まずはクラスの継承は考えずに、1つのクラス内に回復アイテムとしての振る舞いが持てるように処理を設計して実装していきます。

 情報として用意したいものとしては「HPの回復量」です。こちらは public 変数として用意しておいて、インスペクター上から設定できるようにしましょう。

 アイテムとプレイヤーとの当たり判定はどちらに実装してもよいのですが、今回はプレイヤー用のクラス内に OnTriggerEnter メソッドを準備して
アイテムの取得が可能なように変更をします。そのため、アイテム側では当たり判定は行っていません。

 以下が回復アイテム用クラスのスクリプトです。Item_RecoveryLife クラスとします。
なお、プレイヤー用の CharaController クラス内には public 修飾子で宣言した int 型の hp 変数と maxHp 変数が準備されている前提です。


Item_RecoveryLife.cs

<= +ボタンを押すと開きますので、自分なりの実装を行った上で確認をしてみましょう。



3.回復アイテム用ゲームオブジェクトを作成し、設定を行ってからプレファブ化する


 新しいゲームオブジェクトとして Cube か Sphere を1つ作成します。名前をスクリプトと同名の Item_RecoveryLife に変更しましょう。

 こちらに先ほど作成した Item_RecoveryLife のスクリプトをアタッチして、このゲームオブジェクトが回復アイテムとしての振る舞い(役割)を持てるようにしましょう。
インスペクターを確認し、アタッチが出来ていることを確認した上で、HP回復量に数字を入れておきましょう。0 のままだとアイテムを取得しても回復しません。
(この例では目立つようにわざと 0 にしています。)

 3Dオブジェクトを作成すると始めから BoxCollider がアタッチされていますので、こちらの IsTrigger にチェックを入れておきます。


インスペクター画像




 必要であれば、他のアイテムとの区別を行えるように、新しいMaterialを1つ作成します。
そちらに色や、回復アイテム用の画像などを設定して、Item_RecoveryLife が回復アイテムに見えるように変更しましょう。
作成した Material は Item_RecoveryLife ゲームオブジェクトの MeshRenderer の Materials 内の Element 0 の部分にアサインして使用できます。


マテリアルの作成と設定



マテリアルの登録(アサイン)



 なお、ゲーム画面上での見せ方ですが、例えば、Cube で作成した場合、Item_RecoveryLife ゲームオブジェクトのScale.Zを小さくすると薄いパネルのようなアイテムになります。
こちらは適宜変更し、自分の考えているアイテムの形状にしていきましょう。(Cube以外のオブジェクトで作成しても問題ありません)




 最後にタグの設定を行います。まずは Unity に新しい Tag を1つ追加します。Tag の名称は Item にします。
登録後、今後は Item_RecoveryLife ゲームオブジェクトに Item の Tag を設定します。


インスペクター画像




 上記の手順がすべて完了すれば回復アイテム Item_RecoveryLife ゲームオブジェクトの完成です。
こちらをプレファブ化しますが、デバッグを行うため、ヒエラルキー上にある Item_RecoveryLife ゲームオブジェクトはまだ削除しないでおきます。


4.プレイヤーが回復アイテムを取得できるようにし、HPが回復する処理を行う


 プレイヤー側の OnTriggerEnter メソッドを追加・修正することで、回復アイテムを取得できるようにしていきます。
回復アイテムのプレファブにはTagとしてItemを設定しておきました。そこで、当たり判定が発生した場合に
このItemのタグを持つゲームオブジェクトに接触したかどうかを判定することで、回復アイテムのゲームオブジェクトか、
そうではないゲームオブジェクトなのかを判別できるようにします。

 下記に CharaControllerを補記したスクリプトを提示します。修正している部分のみ記載しています。


<= +ボタンを押すと開きますので、自分なりの実装を行った上で確認をしてみましょう。


 以上になります。
 

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


 期待する挙動としては

1.プレイヤーがアイテムを接触すると取得できる。取得できるとHPが回復する。最大値は超えて回復はしない。回復アイテムは破壊される。

 この動きになっていれば完成です。
問題なくデバッグが終了したのであれば、ヒエラルキーにある Item_RecoveryLife ゲームオブジェクトは削除してください。


6.回復アイテムを一定確率で出現(生成)するようにする(敵を倒した場合)


 アイテムの出現方法として、今回の設計では「敵を倒した場合」という条件によって生成されるように設計を考えました。

 敵が破壊される処理のあとに、この条件を入れればよいですから、EnemyControllerクラスに補記していくことが一番よさそうです。

 下記に EnemyController を補記したスクリプトを提示します。修正している部分のみ記載しています。


EnemyController.cs

<= +ボタンを押すと開きますので、自分なりの実装を行った上で確認をしてみましょう。


 スクリプトを修正したら、インスペクターを確認します。アイテムの出現確率の入力と、生成する回復アイテムのプレファブのアサインを忘れずにしておきましょう。


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


 敵を倒してみて、回復アイテムが敵の位置に生成されるかを確認してください。
期待する挙動は以下の流れになります。1と3の挙動が新しい内容です。

1.敵を倒すと、アイテム出現確率で指定した確率で回復アイテムが敵の位置に生成される。
2.プレイヤーがアイテムを接触すると取得できる。取得できるとHPが回復する。最大値は超えて回復はしない。回復アイテムは破壊される。(ここは実装済)
3.敵はアイテムに接触しても取得できないので、アイテムは破壊されない。

 デバッグ用に、敵がアイテムを生成する確率は、最初は 100 に設定しておくことをおすすめします。
生成の挙動が確認できたあとに、生成する確率を下げて、果たして確率に応じた生成になるかを確認しておきます。


<検証事項>


 OnTriggerEnter メソッド内におけるタグによるアイテムの評価ですが、問題点があります。
あくまでもタグによってゲームオブジェクトを回復アイテムであると判断しているため、今後、他のアイテムの種類が追加された場合には、
この判定の方式であると、回復アイテムかどうかを判定するために、さらに新しい分岐を作っていく必要が生じます


<問題点>
private void OnTriggerEnter(Collider col) {
        
        // ゲームオブジェクトのコライダーの侵入を感知したら、Item タグが設定されているかを評価する
        if (col.gameObject.tag == "Item") {

            // さらに、どのアイテムであるかを判断し、異なる処理を実行
            if(col.gameObject.name == "Item_RecoveryLife") {    //  あるいは if(col.gameObject.GetComponent<Item_RecoveryLife>() != null) で判定

                // 引数には CharaController を渡して Item_RecoveryLife 側で Hp の計算が出来るようにする
	        col.gameObject.GetComponent<Item_RecoveryLife>().RecoverHp(this);
            }
            else if(col.gameObject.name == "他のアイテムの名前") {

                // 処理

            }
            else if(col.gameObject.name == "他のアイテムの名前") {

                // 処理

            }
   
      // TODO アイテムの種類が1つ増えたら、ここに、新しいアイテム専用の分岐処理を追加する必要がある

	}
  }

 上記の処理を見るとわかるように、アイテムの種類が3つになっただけでも、それに合わせて、その都度、処理を追加する必要があります。
また、GetComponent メソッドの処理が複数に渡って行われることもあるため、処理に無駄が多くなっています。
GetComponent メソッドは軽い処理ではないので、利用する場合には多用は禁物です。

 この部分を改善するために、クラスの継承の機能を利用します。
次はこのアイテムクラスを親クラスと子クラスに分けてクラスを継承させた作りに変更していきます。

コメントをかく


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

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

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

3D脱出ゲーム(抜粋)

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

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

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

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

3Dトップビューアクション(白猫風)

VideoPlayer イベント連動の実装例

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

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

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

private



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

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