Unityに関連する記事です

 この手順では実際にボスを生成し、倒すことによってボス討伐済の状態に切り替わる処理を実装していきます。


<実装動画 .椒垢寮言と移動>
動画ファイルへのリンク


<実装動画◆.椒垢瞭と押
動画ファイルへのリンク


 以下の内容で順番に実装を進めていきます。

手順25 −ボスの作成と生成処理の実装−
52.ボスの情報を作成する
53.EnemyController を修正して、ボスの情報を利用してボスと通常のエネミーの振る舞いを変える制御する処理を追加する
54.EnemyGenerator スクリプトを修正して、エネミーの生成処理を修正し、ボスの生成処理にも対応できるように変更する



 新しい学習内容は、以下の通りです。

 ・引数を利用して外部のスクリプトから情報を取得して利用する方法
 ・省略可能な引数を持つメソッドを定義する方法と使用方法
 ・DOTweenの補間機能と実装例◆ DOLocalMoveY メソッドー



52.ボスの情報を作成する

1.設計


 エネミーの設計ですが、複数のエネミー用のプレファブを用意する方法ではなく、
1つのエネミー用のプレファブを、生成時に異なる情報を利用して振る舞いを変更するという方法で実装を行います。

 エネミーの数が少ないうちは複数のエネミー用のプレファブを用意してもよいですが
多くなればなるほど管理が煩雑になり、1つずつ情報の設定が必要になるため大変です。

 そのため今回はボス用のプレファブ、ノーマル用のプレファブを数体、というように複数のプレファブを準備するのではなくて
エネミー用のプレファブを生成後に、ボスにするのかノーマルのエネミーにするのかを、エネミー用の情報を参照して設定し、
その情報に基づいたゲームオブジェクトとして振る舞うようにする設計方法です。

 この方法を利用することで、後程エネミー用のデータベース(エネミーごとのデータ情報のまとまり)を作成して運用することにより、
1つのエネミー用のプレファブはデータを参照するだけで、多くのエネミー用のゲームオブジェクトとしてゲームの中に存在出来るようになります。

 まずはここでは、エネミー用のプレファブを利用して、ボス用の設定情報を与えて
同じエネミー用の EnemySet プレファブから異なるゲームオブジェクトとして振る舞わせる方法を学習します。

 エネミー用のデータベースがまだありませんので、ボスなのか、ボス以外なのか、という情報を設定情報として準備し、
この情報を元にして、EnemySet プレファブをボスのゲームオブジェクト、あるいは通常のエネミーのゲームオブジェクトと変更するようにします。

 まずはボスとして生成されたときの状態を確認しておく必要がありますので、どのような状態をボスと定義するのかを設定しましょう。
ここでは、どのようなゲームオブジェクトを作成するのかイメージをつかむために、一度エネミーを作って調整してみます。


2.EnemySet ゲームオブジェクトを Canvas 内の EnemyGenerator の子オブジェクトとして設置する


 Prefabs フォルダにある EnemySet ゲームオブジェクトを、Canvas 内の EnemyGenerator の子オブジェクトとして
ドラッグアンドドロップして設置してください。


ヒエラルキー画像



インスペクター画像



Sceneビュー画像



 続いて、ボスとしての設定を確認します。


3.EnemySet ゲームオブジェクトを調整してボス用の設定を確認する


 どのような設定をボスとして考えていくかですが、今回の場合は、他のエネミーよりもサイズを大きくして、ボス感を表現するようにします。

 EnemySet ゲームオブジェクトの RectTransform コンポーネントの Scale の値を (2, 2, 2) に変更してください。倍のサイズになります。
自動的にコライダーのサイズも数値は同じですが、調整されて画像と同じサイズになります。
これは、Scale を基準にコライダーのサイズは設定されているため、Scale が変更されるとコライダーも一緒に変更になるためです。


インスペクター画像



コライダー



 EnemySet ゲームオブジェクトのクローンが生成された際に、このサイズ変更の処理と制御をスクリプトから行うようにします。
そのためにはどのような処理をロジックとして考えればよいでしょうか。

 それでは、イメージがつかめたと思いますので、EnemyGenerator ゲームオブジェクトの子オブジェクトに作成した EnemySet ゲームオブジェクトは不要です。
ヒエラルキーから EnemySet ゲームオブジェクトは削除しておいてください。


53.EnemyController を修正して、ボスの情報を利用してボスと通常のエネミーの振る舞いを変える制御する処理を追加する

1.設計


 EnemySet ゲームオブジェクトの Scale のサイズを変更する処理を実装するには
EnemySet ゲームオブジェクトにアタッチされている EnemyController スクリプトに処理を記述する方法が一番わかりやすいでしょう。

 EnemyController スクリプトには SetUpEnemy メソッドという、エネミーの設定を行うメソッドがありますので、
こちらの中でサイズの変更の処理を追加すれば生成されたエネミーのサイズを変更することが可能になります。



 問題は2つあります。

 SetUpEnemy メソッドはすべてのエネミーの生成時に利用されるメソッドです。
そのため、ボスであるかどうかは関係なく、実行されるメソッドになっています。
つまり、ボスの場合にはサイズを変更する、という制御処理を追加がないと、すべてのエネミーのサイズが大きくなってしまいます。

 もう1つは、上記の制御処理を行うための「ボスなのか、ボスではないのか」という設定情報はどこにもありません
そのため、この情報を用意することによってはじめて、上記の分岐処理の条件文を作成することができ、
ボスとボス以外のエネミーで処理を分岐することが出来るようになります。

 どんな分岐のロジックを作りたいか、そのためにはどんな情報が必要か、ということを考えておくことが大切です。



 今回は引数を利用して、新しい考え方を学習します。

 エネミーがボスであるか、ボスではないか、という情報は EnemyController スクリプト自体に用意することはできます。
ボスではない、という情報を EnemyController スクリプトが初期設定で持っているとしたら、それは逆にボスである、という情報を持ってくることはできません。

 つまりボスであるかないか、という設定情報自体の用意はしておいてもよいが、
その振る舞いを決定するのは EnemyController スクリプトでなく、別のスクリプトに任せる、という考え方です。

 EnemyController スクリプトが実行されるのは、このスクリプトがアタッチしているゲームオブジェクトが生成されたタイミングですから、
EnemySet ゲームオブジェクトのクローンが生成されて始めて EnemyController スクリプトが有効になります。

 そのため、エネミーを生成する EnemyGenerator スクリプトが生成したタイミング
「今回の生成するエネミーは通常です」「今回生成するエネミーはボスです」というように
EnemyController スクリプトに役割を与えるようにすれば、その情報を受け取って、EnemyController スクリプトがボスの有無の情報を設定できます。

 それを利用して分岐条件を作成すれば、ボスとしての EnemyController スクリプトになるのか、
あるいは通常のボスではない EnemyController スクリプトになるのか、判断をつけることが可能になります。
 
 この方法を使って1つのエネミー用のプレファブをボスにしたり、通常のエネミーにしたり、振る舞いを自動的に変えるようにしていきます。

 引数の利用に際して、今回は以下のデフォルト引数の機能を利用しますので、こちらも学習しましょう。



 ボスとして振る舞う場合には、サイズを変更する以外にも、hp を 3 倍にする移動方法を変更する、という部分も合わせて考えて設計を行ってください。

 通常のエネミーの場合は、上方向から下方向に常に移動を行う処理が Update メソッドにて実行されています。
そのため、ボスの場合にはこの移動処理を行わないようにして、画面の上方向から移動してきたら、一定の位置で停止するような移動処理を考えてください。
その場合には、DOTween 機能を利用すると、瞬間移動しないで一定の位置まで移動させることができますので、こちらも合わせて考えてみましょう。



 また、ボスの場合に限り、倒された場合にボス討伐済の状態にする必要があります
つまり、ボスの hp が 0 以下になった際に、この制御処理の追加も必要になります。
ボス討伐済の状態は EnemyGenerator スクリプトが管理している情報ですので、
ボスの場合には、EnemyGenerator スクリプトの情報を扱えるようにしておく必要があります。


2.<デフォルト引数 −省略可能な引数ー を持つメソッドを定義する方法と使用方法>


 省略可能な引数とはデフォルト引数とも呼ばれます。メソッドに引数を用意する際に、あらかじめ初期値を設定(初期化)しておくことで
その引数を省略した場合には初期値を使用し、省略せずに記述した場合にはその値を使用する、という定義になっています。

<今回のケースの場合のメソッドの定義>
 public void SetUpEnemy(bool isBoss = false)

 通常の引数とは異なり、型、変数名の宣言に加えてイコールで初期化を行っています
これがデフォルト引数(省略した引数)の定義の方法になります。
なお、複数の引数を持つメソッドの場合、この省略書式は、省略していない引数の宣言が終わってから書かないとエラーになります

<複数の引数を持つ場合のメソッドでの省略引数の定義>
 1.エラーにならない場合(省略していない引数を書いた後に省略引数を定義する)
 public void SetUpEnemy(int x, GameObject obj, bool isBoss = false)

 2.エラーになる場合(省略していない引数が省略引数よりも後ろに定義されている)
  public void UpdateDisplayScore(int x, bool isBoss = false, GameObject obj)



 省略引数を持つメソッドを呼び出す命令には2つの方法があります。
1つは省略引数を書かないで呼び出す方法と、省略引数を書いて呼び出す方法です。

  <省略引数を省略しない場合の命令>
 SetUpEnemy(true);

 <省略引数を省略する場合の命令>
 SetUpEnemy();

 上記の場合には、true が引数として渡されます。
 下記の場合には引数が省略されていますので、省略引数で初期化して宣言している false が引数として渡されます
もちろん bool 型の変数を渡すことも可能です。

 省略引数の値を利用することがほとんどで、たまに引数を指定して渡すようなメソッドの場合には、
引数の値が必要な場合にだけメソッドの引数を記述すればよいことになりますので、その都度、引数を書く手間が省けます。


3.EnemyController を修正し、事前に調整しておいた情報を参考にボスの情報を設定する処理を追加する


 設計に基づいて、1つずつ順番に処理を考えて実装するにはどんなロジックを組めばいいか、考えて実装してみてください。
一度にすべてを実装しようとしないことが大切です

 次の手順では EnemyGenerator スクリプトも変更を行いますので、どの部分が変更になりそうか、
その部分も考えておくと全体の流れが見えやすくなって設計を考えやすくなります。


EnemyController.cs


 スクリプトを修正したらセーブします。

 この実装例と同じで実装を行わなければならない訳ではありません。
 例えば、AddtionalSetUpEnemy メソッドの処理は、SetUpEnemy メソッドの引数に情報を追加して、
通常のエネミーの場合にも受け取るようにしておいても問題ありません。



 Prefabs フォルダにある EnemySet ゲームオブジェクトのインスペクターを確認します。
新しく表示される変数はありませんので、アサインが外れていなければ問題ありません。


EnemySet ゲームオブジェクト インスペクター画像




4.<DOTweenの機能と実装例◆ DOLocalMoveY メソッド−>


 EnemyController スクリプトの SetUpEnemy メソッドでは、DoTweenによる補間処理を実装しています。
今回利用しているメソッドについて説明します。
DOLocalMoveY (float endValue, float duration)

 DOLocalMoveY メソッドは、ゲームオブジェクトの位置のうち、Y軸(transform.localPosition.Y)だけを指定して移動させる処理です。
移動時に補間処理を行うことでアニメーションしているように見せてくれます

 このメソッドは処理を行いたいゲームオブジェクトの、transfrom に対して実行します。ここではこのスクリプトがアタッチされているゲームオブジェクトを移動させる命令を行いたいので
このゲームオブジェクトのTransform コンポーネントが代入されている transform 変数に対して処理を行うようにしています。

  // ボスの位置を徐々に下方向に変更
  transform.DOLocalMoveY(transform.localPosition.y - 500, 3.0f);

 transform.DOLocalMoveY()の第1引数はfloat型で、移動させる位置を指定します。
この処理では、エネミーの位置を下方向に動かしたいので (現在位置 - 500.0f) を指定しています。

 第2引数は float 型で、移動する際にかける時間を指定します。今回は 3.0f と実数(変数指定も可能)を指定しているので
3 秒かけて、このスクリプトがアタッチされているゲームオブジェクトのローカル座標の Y 軸の位置を現在位置から マイナス 500 方向移動をさせる、という命令になります。

 これをゲーム画面で見ると、ボスが画面の上方向から下方向にむかってゆっくりと移動してくるように演出することが出来ます。
そしてそのまま停止します。もしもボスが一瞬で移動するのとアニメ演出して移動するのとでは演出に大きな差が出ますので、DOTween 機能は是非習得しましょう。


<実行動画 ボスの移動のアニメ演出>
動画ファイルへのリンク



54.EnemyGenerator スクリプトを修正して、エネミーの生成処理を修正し、ボスの生成処理にも対応できるように変更する

1.設計


 EnemyController スクリプトを修正し、SetUpEnemy メソッドにて、「ボスか、ボスではないか」という情報を bool 型にて受け取れるように処理を変更しました。
あとは、EnemyGenerator スクリプト側でエネミーを生成した際に、「ボス」「ボスではない」という情報を設定して渡すことが出来れば
EnemyControler スクリプト側で自動的に分岐の処理を行って「ボス」のエネミーか、「ボスではない」エネミーか、振る舞いを変えることが出来ます。

 すでにボス生成用のメソッドは作成してありますが、いままでは Debug のみでしたので、その部分を修正してボスが実際に生成される処理を記述しましょう。

 先ほど学習したデフォルト引数を利用することによって、ボス生成用のメソッドを新しく作る必要なく、
GenerateEnemy メソッド1つでボス用とボス以外用のエネミー生成と使い分けることが出来ます。
どのように活用すればよいか、ロジックを考えてみてください。


2.EnemyGenerator スクリプトを修正し、エネミーの生成処理を修正し、EnemyController スクリプトにボスの有無の情報を渡すようする。


 設計に基づいて処理のロジックを考えて実装を行ってみてください。
Debug を利用して処理の順番を確認してありますので、Debug や TODO の機能を参考にしてください。
またこれらの実装が終了した部分についてはコメントアウトするか削除してください。

 また、デフォルト引数を上手く活用することで修正する部分を少なくすることが出来ます。
省略されている情報は通常のエネミーの生成用の情報、記述する場合にはボスの生成の情報と考えてみてください。


EnemyGenerator.cs

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


 スクリプトを修正したらセーブします。
この実装例もあくまで参考例です。自分で実装したものを優先してください。
その場合には、こういった実装もできる、という形で処理を確認しておいてください。



 EnemyGenerator ゲームオブジェクトのインスペクターを確認し、EnemyGenerator スクリプトの情報を確認します。
新しく public 修飾子で宣言した変数の表示が追加されていれば問題ありません。

EnemyGenerator ゲームオブジェクト インスペクター画像




3.ゲームを実行して確認する


 すべての実装が完了しましたので、ゲームを実行してエネミーの生成完了の状態にしてください。
続けてボスが生成されて、ボスとしての振る舞いを行って、同じエネミーのプレファブがボス用のゲームオブジェクトになっていれば制御成功です。
生成されたボスのゲームオブジェクトを確認しておきましょう。Scale や hp の値も変更になっています。


<実行動画 .┘優漾爾寮言完了状態になるボスが生成されて移動してくる>
動画ファイルへのリンク


<実行動画◆.椒垢鯑と欧垢襪函isBossDestroyed 変数と isGameUp 変数が true になり、ゲーム終了の状態になる>
動画ファイルへのリンク


 もしもボスが生成されなかったり、生成されてもボスとして生成されない場合には一連の処理の流れを見直してみてください。
EnemyGenerator スクリプト側が EnemyController スクリプト側に対して、ボスの有無の情報を渡す設計になっていない可能性があります。


 以上でこの手順は終了です。

 次は 手順26 −ステージクリア表示の作成と実装− です。

コメントをかく


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

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

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

3D脱出ゲーム(抜粋)

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

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

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

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

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

VideoPlayer イベント連動の実装例

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

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

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

private



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

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