Unityに関連する記事です

 バレット用のプレファブと BulletDataSO スクリプタブル・オブジェクトを利用し、クローンされたバレットのゲームオブジェクトにバレットのデータを設定し、
同じプレファブから異なるバレットを自動的に生成する処理を実装します。手法はエネミーの場合と同じです。そのため、教材を見ずに、以前の実装を見ながら進めてみてもいいでしょう。

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

発展21 ーバレット用のデータベースの利用 
43.Bullet スクリプトを修正し、BulletDataSO スクリプタブル・オブジェクトのデータを参照して反映する処理を追加する
44.GameData スクリプト、BulletSelectManager スクリプト、PlayerController スクリプトを修正し、バレット用のプレファブに BulletDataSO スクリプタブル・オブジェクトのデータを参照して設定を反映する



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

 ・処理の全体像から、ロジックを組み立てて実装を行う



43.Bullet スクリプトを修正し、BulletDataSO スクリプタブル・オブジェクトのデータを参照して反映する処理を追加する

1.設計


 BulletDataSO スクリプタブル・オブジェクトにバレットのデータを登録しました。
こちらの情報をゲーム内でも利用できる状態にして、バレットに反映できるように処理を実装していきます。



 スクリプタブル・オブジェクトは、スクリプト内に同名の型名で変数を作成することで利用することが可能になります。

<スクリプタブル・オブジェクトを利用できる状態にする>
  public BulletDataSO bulletDataSO;

 上記のように変数として宣言することにより、変数を利用してスクリプタブル・オブジェクトの情報をゲーム内に利用することが出来ます。

 宣言の方法は他の変数と変わりません。また、public 修飾子にして宣言しておくことにより、
インスペクターより登録が出来る他、外部のスクリプトからも参照して利用することが可能です。これも他の変数と同じです。



 現在、バレットのデータとしてゲーム内で利用されている情報は、Bullet スクリプトにある、以下の2つの変数の情報です。

    [Header("バレットの速度")]
    public float bulletSpeed;

    [Header("バレットの攻撃力")]
    public int bulletPower;

 いままではこちらの変数に対してインスペクターより設定を行って数値を決めていました。
そのためバレットのゲームオブジェクトをプレファブのクローンとして生成すると、常に同じ速度と攻撃力を持っているバレットが生成されていました。
異なるバレットの情報を利用することを考えると、この設計では適用することができませんので、運用方法を変更する必要があります。
 


 この変数の設定の部分に、今回作成した BulletDataSO スクリプタブル・オブジェクトのバレットのデータを利用するように処理の変更を行います。
生成されるクローンのゲームオブジェクトは同じですが、その内容・情報に対して、バレットのデータを反映することによって、生成されたバレットの振る舞いを変更します。

 今回はプレイヤーのバレットのデータとして情報を登録してありますので、そのデータを利用して、プレイヤーのバレットとして振る舞うように制御します。

 この処理を自動化して、バレットが生成されたときにバレットのデータの情報に合わせて、バレットとしての振る舞いも自動的に変わるようにします。
このような設計にすると、1つのプレファブから、バレットのデータベースに登録されているすべてのバレットを作り出すことが可能になります。


2.Bullet スクリプトを修正し、BulletDataSO スクリプタブル・オブジェクトのデータを参照して反映する処理を追加する


 設計に基づいて、インスペクターで設定していた情報を BulletDataSO スクリプタブル・オブジェクトの BulletData クラスの情報を参照するように変更します。

 まずは BulletData クラスの情報を扱えるように、BulletData 型の変数を用意します。この変数に、バレットとして必要なすべてのデータが入ることになります。
速度、攻撃力、そしてバレットの画像の情報などが入っていますので、このデータを利用することで「どのようなバレットとして振る舞うか」決まります。
この変数を利用することによって、BulletData クラスの情報を参照して利用出来るようになります。

 BulletData クラスの情報は、外部のスクリプトから引数で受け取るように設計します。
いままで ShotBullet メソッドで Vector3 型の発射する方向の情報を受け取っていましたが、この引数に BulletData 型を宣言を追加して、ここでバレットのデータを受け取れるようにします。

 ここで大切なポイントがあります。
 BulletData クラスの情報を決定するのは、Bullet スクリプト側ではありません。これもエネミーと同じ設計です。
Bullet スクリプトでは、引数として届いた BulletData クラスの情報を利用して、設定を行うことで、バレットのデータを反映してエネミーに役割を与えることが仕事です。

 生成されたバレットのクローンに対して、バレットのデータを決定し、「この情報を使ってバレットに役割を与えて振る舞いを変えてください」と命令を出すのはバレットを生成している側、
つまり PlayerController スクリプト側での処理になります。

 この役割分担の考え方についてもしっかりと学習して理解を深めてください。



 以上のことより、この BulletData クラスに含まれている情報については、このスクリプト内で個別に設定を行う必要がなくなります
対象となる変数は bulletSpeed 変数と bulletPower 変数です。このうち、bulletPower 変数については後程変更を行います。
何故ならば、この変数は外部のスクリプトにおいて参照して利用されている値であるため、この値を修正したり削除してしまうと、Bullet スクリプト以外の場所にエラーが出てしまうからです。

 BulletData クラスには、バレットの種類の情報とバレットの利用者の情報も含まれており、BulletType 型と LiberalType 型という enum がそれに当たります。
この情報を参照すれば、生成されたバレットがどのような種類のバレットなのか、それを発射するのはプレイヤーなのか、あるいはエネミーなのか、それらを判断をすることが可能です。

 BulletData クラス内の変数はすべて public 修飾子によって宣言されています。そのため、BulletData クラスの情報を取得している変数からは
これらの public 修飾子の変数の情報をすべて利用できます
例えば、LiberalType を参照したい場合には以下のようになります。

  // BulletData クラスに登録されている LiberalType の情報が、Boss の列挙子である場合
  if(bulletData.liberalType == EnemyType.Boss) {  }

 この処理を利用して、BulletData から攻撃力、速度、そしてバレットの画像の情報を参照して、バレットに設定を行います。
BulletData の取得は ShotBullet メソッドを通じて行いますので、その後、そのデータを利用してバレットの画像を設定するように設計します。
画像を変更するためには、Image コンポーネントの情報が必要になりますので、SerializeField 属性で変数を宣言しておきます。
つまり、この手順を実装することによって、いままで Knob の画像であったバレットの画像が、バレットのデータとして登録した画像に変更されてゲーム内に反映されることになります。

 それ以外の情報も BulletData には含まれていますが、現在はこれらの情報だけを活用します。

 以前から学習しているように、変数に代入されている情報からは、public 修飾子の情報をさらに取得して利用できます
ピリオドを使った処理について理解を深めていってください。


Bullet.cs

 <= クリックしたら開きます


 スクリプトを修正したら、プレファブの Bullet ゲームオブジェクトのインスペクターを確認します。
public 修飾子と SerializeField 属性で宣言した情報を表示されていれば問題ありません。


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



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


3.Bullet ゲームオブジェクトの設定を行う


 Prefabs フォルダにある Bullet ゲームオブジェクトを選択して、インスペクターの一番上にある Open Prefab ボタンを押して、プレファブの編集モードにしてください。

 新しく追加された変数のうち、bulletData 変数は何も設定をしないでください
この部分に、PlayerContorller スクリプト側から届いた bulletData の情報が自動的に入ります
そうすることによって、このデータを利用してバレットの役割、振る舞いが自動的に設定されます


bulletData


 imgImage 変数には、同名のゲームオブジェクトをドラッグアンドドロップしてアサインしてください。
Image コンポーネントの情報が登録されます。この変数を利用して、BulletData クラスに登録されている画像の情報を利用し、
バレットが生成されるたびに、自動的にバレットの画像を設定して差し替えるようにします。


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



 以上で設定は完了です。


44.GameData スクリプト、BulletSelectManager スクリプト、PlayerController スクリプトを修正し、バレット用のプレファブに BulletDataSO スクリプタブル・オブジェクトのデータを参照して設定を反映する

1.設計


 Bullet スクリプトには BulletData を利用するための処理を実装することができました。
あとは、BulletData をどのようにすれば Bullet スクリプトに届けることができるのか、それを考えていきます。
 
 以前にも学習したように、ロジックを考えるためには、目的とする全体の処理のイメージを作ること、その処理のスタート地点とゴール地点を明確にすることが大切です。
今回であれば、スタート地点は生成されたバレットになりますし、ゴール地点は Bullet スクリプトに BulletData を届けることです。
生成されたバレット、ということは、バレットを生成しているスクリプトになりますし、ゴール地点はそのまま Bullet スクリプトの ShotBullet メソッドになります。

 これを主軸に、どのようなロジックを考えてスクリプトに命令を出していければよいか考えていくことになりますが、
まずは、Bullet スクリプトへ渡すための BulletData をどのようにして管理するのか、その方法から考えてみてください。



 現在ゲーム画面をタップするとバレットが生成されます。ただしこのバレットにはまだ何も情報が届いていません。
そのため、BulletData は空っぽの状態です。ここにバレットの情報を届くようにすれば、ゴール地点が完成です。

 さて、届けるバレットのデータとは、いったい何になるのでしょうか。

 今後は、バレットの選択が入ってきますが、現在はまだそのような要素はありませんので、バレットのデータに登録されている情報から考えます。
現在はプレイヤー用のバレットのデータのみ登録されています。これを初期のバレットのデータとして利用すると考えてください。
以上のことより、ゲームの最初は、初期設定となるバレットのデータを設定し、管理することができれば、そのデータを BulletData として Bullet スクリプトへと渡すことが出来そうです。
 
 つまり、「現在使用しているバレットのデータ」という情報を設定し、管理する必要があるということになります。
こちらの情報をどのスクリプトで管理するようにするかも、今後の設定に関わってきます
先ほども書いたように、今後はバレットを選択する機能が追加される予定です。管理する、ということは、バレットのデータをバレットを選択するたびに更新し、
常に選択された状態で管理をする、という必要が生まれてきます。

 こういった部分までを考えて、どのスクリプトに情報を管理させていけばよいかを検討して設計を行っていく必要がある、ということになります。



 今回のゲームにはどのスクリプトでも参照ができるスクリプトとして、GameData スクリプトがあります。
こちらに、現在使用しているバレットのデータを管理してもらうようにします。

 理由としては、どのスクリプトからでも参照ができるという利点を生かすためです。
先を考えると、現在使用しているバレットを参照する以外に、そのバレットの情報を変更したり、という処理も必要になりますので、
管理しているスクリプトは、色々なスクリプトから呼び出されたりする可能性が高いはずです。
そういったものは、GameData スクリプトのようなシングルトンクラスに管理をさせることで利便性が増します

 例えば3つのスクリプトに修正が必要な状況になったとき、GameData スクリプトであれば、
各スクリプトに変数の宣言なしで利用できますので不必要に変数を増やすことも防ぐことが出来ます。

 以上のことを考えると、現在使用しているバレットのデータの情報を GameData スクリプトで管理をさせて
設定(変更)する際や、情報を取得するためのメソッドを用意しておいて、そのメソッドを実行することで情報を変更したり、参照できるような設計にします。



 初期バレットの設定については、GameData スクリプトに用意したメソッドを実行することで設定・変更できるようにするとした場合、
では次に、どのスクリプトでこの初期バレットの設定の処理を実行すればいいのかを考えていきます。

 バレットのデータは BulletDataSO スクリプタブル・オブジェクトに登録されているものを利用するのですから、
必然的に、この BulletDataSO スクリプタブル・オブジェクトを管理するスクリプトから、GameData スクリプトに用意した設定用のメソッドを実行することが理想的です。
引数に BulletData を渡すようにすれば、それをそのまま GameData スクリプトに用意した変数に代入(登録)することが可能になります。

 以上のことをふまえて、BulletDataSO スクリプタブル・オブジェクトを管理するスクリプトをどのスクリプトにするか、考えてみてください。



 以上で初期バレットの設定については処理の流れが見えました。最後は、スタート地点の修正です。
バレットを生成しているのは PlayerController スクリプトですし、こちらから現在も ShotBullet メソッドを実行しています。
ShotBullet メソッドは先ほど Bullet スクリプトを修正した際に BulletData を引数で受け取れるように窓口(引数)を用意してあります。

 このメソッドに GameData スクリプトを参照して、現在使用しているバレットのデータを引数として渡すようにすれば、
BulletData の情報を無事に ShotBullet メソッドに届けることが出来ます。



 処理のイメージはわきましたか?
文字ベースで処理をまとめてきましたが、端的に処理の順番と修正点をまとめると次のようになります。

<ロジックの流れ>
 1.GameData スクリプトを修正して、現在使用しているバレットのデータを登録するための変数を宣言する。また、このバレットのデータを変更したり、参照したりできるメソッドを用意する
 2.BulletSelectManager スクリプトを修正して、BulletDataSO スクリプタブル・オブジェクトを利用して、初期のバレットのデータを、GameData スクリプトに用意したバレットのデータの変数に代入する
 3.PlayerController スクリプトを修正して、バレットを生成した際に Bullet スクリプトの引数に、方向の情報と一緒に、現在使用しているバレットのデータを取得して渡す
〇4.Bullet スクリプトに PlayerController スクリプトから方向の情報とバレットのデータ情報が届くので、それを利用してバレットの振る舞い(攻撃力、速度、画像など)を設定する

 〇4の部分が実装の終了している部分になりますので、残りの部分のロジックを実装していきます。


2.GameData スクリプトを修正する


 現在選択しているバレットのデータを保持し、それを参照させるための変数とメソッドを用意します。
GameData クラスで管理しておくことにより、いずれのスクリプトからも参照が容易になります。


GameData.cs

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


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

 GameData ゲームオブジェクトのインスペクターを確認します。
新しく SerializeField属性で宣言した BulletData 型の変数が追加されています。
こちらに現在ゲーム内で使用しているバレットのデータを代入して利用していきます。


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




3.BulletSelectManager スクリプトを修正して、BulletDataSO スクリプタブル・オブジェクトを利用できるようにして初期バレットの設定を行う


 BulletSelectManager スクリプトに BulletDataSO スクリプタブル・オブジェクトを管理させて利用できるようにします。
また、初期のバレットの情報を GameData クラス内に登録し、PlayerController スクリプトで参照して利用出来るようにしておきます。


BulletSelectManager.cs


 スクリプトを作成したらセーブします。
BulletSelectManager ゲームオブジェクトのインスペクターを確認し、新しく SerializeField 属性で宣言した変数が追加されていることと確認します。


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



4.BulletSelectManager ゲームオブジェクトの設定を行う


 bulletDataSO 変数に、Datas フォルダにある BulletDataSO スクリプタブル・オブジェクトをドラッグアンドドロップして、変数にアサインしてください。
BulletDataSO スクリプトではありませんので、注意してください。


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



 以上で設定は完了です。


5.PlayerController スクリプトを修正する


 現在は、バレットの生成処理を行ったあとに、Bullet スクリプトに対して、発射する方向を ShotBullet メソッドに引数を利用して値を渡しています。
この引数には BulletData 型の情報が追加されていますので、GameData スクリプトに設定されている現在使用しているバレットのデータを引数として渡すように処理を追加します。
GameData スクリプトには現在使用しているバレットのデータを取得するためのメソッドが用意されていますので、そちらの戻り値を活用して引数を指定しましょう。


PlayerController.cs

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


 スクリプトを作成したらセーブします。


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


 すべての実装が完了しましたので、ゲームを実行して順番に処理の内容を確認していきます。

 まずはゲーム実行し、バレット選択ボタンが4つ生成されてから、ゲームを一時停止してください。
GameData ゲームオブジェクトのインスペクターを確認して、currentBulletData 変数の値を確認してください。
ここに初期バレットのデータが代入されていれば制御成功です。


<GameData ゲームオブジェクトのインスペクター画像 ゲームを実行すると初期バレットのデータが代入される>





 ゲームを再開して、バレットを発射してみてください。生成された Bullet ゲームオブジェクトにも BulletData の値が代入されて
そのデータに基づいたバレットとして振る舞っていれば制御成功です。画像だけではなく、速度、攻撃力などの値も確認してみてください。


<生成された Bullet ゲームオブジェクトの BulletData に初期バレットのデータが代入される>





<実装動画 GameData ゲームオブジェクトのインスペクターの BulletData に初期バレットのデータが代入される>
動画ファイルへのリンク


<実装動画◆GameData の BulletData を利用し、発射されたバレットの画像が変更されている>
動画ファイルへのリンク


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

 次は 発展22 −バレット用のデータベースの利用◆ です。

コメントをかく


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

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

Menu



技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

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

3D脱出ゲーム(抜粋)

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

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

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

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

VideoPlayer イベント連動の実装例

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

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

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

private



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

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