Unityに関連する記事です

ー障害物用のゲームオブジェクトの実装ー


 この手順では、障害物用のゲームオブジェクトの作成と制御を行います。


Gameビュー画像



 ・障害物用のゲームオブジェクトの作成と制御

<実装動画 Sceneビュー 侵入したキャラを食べて吐き出して、小さくなり消える>
https://gyazo.com/a64244c7a280f9de9add1b11b8e6bec2


<実装動画 Gameビュー 食べられるとキャラが口の中の中央に移動する>
https://gyazo.com/0178daa7e52ced610b8f1382d0ebf946



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

 ・TryGetComponent()メソッドとoutキーワード宣言
 ・DORotate メソッドの RotateMode オプション


1.設計


 障害物用のゲームオブジェクトを作成し、スクリプトを利用して挙動を制御するようにします。
 
 以下の内容を実装し、制御を行えるようにします。

 ・障害物用のゲームオブジェクトにコライダーを用意し、IsTrigger に設定し、侵入判定を行えるようにする
 ・コライダーに侵入したゲームオブジェクトについては、キャラ以外は判定を行わないようにする
 ・侵入したゲームオブジェクトがキャラのゲームオブジェクトである場合、食べる処理を行うメソッドを呼び出す。

 ・食べる処理のメソッドでは、以下の処理を上から順番に行う

 1.障害物用のゲームオブジェクトのコライダーをオフにし、重複判定を防ぐ
 2.障害物用のゲームオブジェクトの口の中にキャラのゲームオブジェクトを移動させて、コライダーのどこに侵入しても口の中にキャラが入るようにする
 3.食べるアニメ再生(attack ステート)を行う
 4.☆ 食べられている間は、キャラは操作不能になる。また落下も停止する
 5.アニメの再生終了に合わせて、キャラを上方向へ吐き出す(キャラを上方向へ移動させる)
 6.キャラを回転させる(吐き出されたのがわかるようにする演出)
 7.☆ 吐き出されたキャラは再度、落下と移動が再開される
 8.☆ 食べられてしまった場合のプレイヤーへのペナルティは、得点の半減。小数点は切り上げる
 9.障害物用のゲームオブジェクトを徐々に小さくなるアニメ演出させながら破壊する

 3つある ☆ の部分については、キャラ側での制御が必要になる部分ですので、PlayerController スクリプトに処理を追加します。
(障害物用のスクリプトでも制御はできますが、今回は、処理を分担して担当するようにします)

 それ以外の部分については、すべて障害物用のスクリプトに用意し、制御を行うようにします。
 
 どの部分でどのような処理が必要になるか、後程スクリプトを作成しますので、自分なりの制御の方法を考えておいてください。

 例えば、「アニメの再生の終了に合わせて、〜」という処理は、別の考え方をすると、「アニメの再生の終了まで、次の処理が動かないようにしておく」必要がありますので
この部分はコルーチン処理を利用して一時処理を中断させる、というように、制御するための情報を元にロジックをイメージしてみましょう。
そうした場合、食べる処理を行うメソッド自体をコルーチンメソッドにするのか、あるいはこの部分だけをコルーチンメソッドを呼び出して実行するのか、などの設計方法が生まれてきます。

 今回の場合は、侵入したゲームオブジェクトの判定には OnTriggerEnter メソッド、そのメソッド内でキャラが侵入したと判定された場合には
食べる処理を行うメソッドをコルーチンとして呼び出すように設定しています。そして食べる処理のメソッド内で、上記の番号順に処理を制御しています。

 最初に、障害物用のゲームオブジェクトの作成と設定を行います。続いて、PlayerController スクリプトの修正、新しいスクリプトの作成の順番で実装していきます。

2.障害物用の ObstacleFlower ゲームオブジェクトを作成する


 インポートされているアセットの中から障害物用のゲームオブジェクトを選択して利用します。
ここでは以下のパスにあるゲームオブジェクトを利用していますが、他のゲームオブジェクトでも構いません。


パス
Assets/JKT_Art/Animals/flower_monster/FLOWER.prefab

フォルダ画像



 選択した FLOWER ゲームオブジェクトをヒエラルキーにドラッグアンドドロップしてゲームに追加します。


ヒエラルキー画像




 名前を ObstacleFlower に変更してください。


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



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


 ObstacleFlower ゲームオブジェクトの設定を行います。

1.Transform

 次の作業を行いやすくするために、Position を (0, 80, 0) のようにして、空中に設置するようにしてください

 また大きさを調整します。Scale の値を (0.5f, 0.5f, 0.5f) にしてください
この値はゲームを実行して遊びながら適宜な大きさに変更にしてください。


ObstacleFlower ゲームオブジェクト Transform コンポーネント



2.BoxCollider

 インスペクターの一番下にある Add Componet ボタンを押して、BoxCollider コンポーネントを追加してください。

 追加した BoxCollider コンポーネントを確認し、最初に IsTrigger のスイッチのチェックを入れてオンにしてください

 続いて、Sceneビュー、あるいは BoxCollider の Edit Collider の部分で、BoxCollider の大きさを変更します。
ゲームオブジェクトの大きさを基準に、下記の画像を参考にしてください。


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



BoxCollider Sceneビュー画像



BoxCollider Sceneビュー画像



BoxCollider Sceneビュー画像



 以上で、BoxCollider コンポーネントの設定は完了です。


3.Animator ビュー

 ObstacleFlower ゲームオブジェクトには Animator コンポーネントがアタッチされており、始めから Animator 用の コントローラーが設定されています。

 ObstacleFlower ゲームオブジェクトを選択した状態で、Animatorビューのタブを押してください


Animator ビュー



 こちらには idle と attack というステートが登録されており、それぞれが矢印(トランジション)によって遷移がつながっている状態です。

 ゲームを実行すると idle の状態がループ再生されるようになっています。
attack のステートにはゲームオブジェクト用の攻撃アニメーションが登録されています。食べて吐き出すアニメーションです。

 Parameters に attack という Trigger 型のパラメータの設定がありますので、こちらの値を利用して
タイミングよく attack のステートに切り替えるように制御を行います。ここでは設定の確認のみで問題ありません。
どのように処理を制御すればアニメーションの遷移が行えるのかを覚えておいてください。


 以上で、障害物用のゲームオブジェクトの作成は完成です。

 続いて、スクリプトを修正、作成します。最初に、PlayerController スクリプトを修正して、処理の制御に必要なメソッドの追加を行います。
そののち、このメソッドを呼び出す命令が記述されている、新しい ObstacleFlower スクリプトの作成を行います。


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


 新しい変数の追加はありません。また、既存のメソッドへの修正や追加もありません。

 新しいメソッドを3つ作成し、キャラの制御とスコアの制御を行います。

 StopMove メソッドを実行すると、Rigidbody コンポーネントの持つ IsKinematic のスイッチがオンになり、物理演算を停止し、キャラの速度を 0 にして落下も含めて停止させます。
Velocity の値も更新されなくなるため、キー入力を行ってもキャラが移動しないようになります。
このメソッドを ObstacleFlower のゲームオブジェクトに侵入した際に呼び出すことで、キャラの移動ができないように制御を行っています。

 ResumeMove メソッドでは、逆に、IsKinematic のスイッチをオフにし、いままでの状態に戻して物理演算を有効にします。
また落下速度を与えて、キャラが再び落下するようにします。物理演算が開始されれば Velocity の値が更新されるようになりますので、キー入力による移動が復活します。

 HalveScore メソッドでは、スコアの値を半分にする処理を行っています。CeilToInt メソッドを利用していますので、計算結果に小数点が発生した場合には切り上げ処理を行います。
また、画面上のスコア表示も、この半分になった値で更新を行います。

 いずれのメソッドも、ObstacleFlower スクリプトより、適宜な処理のタイミングで呼び出されることによって、キャラの移動制御とスコアの制御を行っています。


PlayerController.cs

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



 スクリプトの修正が完成したら、Penguin ゲームオブジェクトのインスペクターから PlayerController スクリプトを確認します。
新しく SerializeField属性で宣言している変数はありませんので、元からある各変数のアサインが外れていなければ問題ありません。


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



 次に、ObstacleFlower スクリプトを作成します。


5.ObstacleFlower スクリプトを作成する


 新しいスクリプトを作成します。このスクリプトは、障害物用の ObstacleFlower ゲームオブジェクトにアタッチするためのものです。

 Scripts フォルダ内で右クリックをしてメニューを開き、Create => C# Script を選択します。名前を ObstacleFlower に変更して、スクリプトを記述します。

 このスクリプトには、障害物用のゲームオブジェクトの制御(食べた時のアニメ再生)、PlayerController 側の制御(キャラの移動を停止し、食べた後に吐き出す)が用意されています。
どのような処理が、どのような順番で制御されているかを把握しながら、処理を記述してください。

 OnTriggerEnter メソッドを利用して、ObstacleFlower ゲームオブジェクトにアタッチされている BoxCollider コンポーネントへの侵入時に判定を行えるようにします。
どのゲームオブジェクトが侵入しても判定を行ってしまうため、花輪や水面のゲームオブジェクトについては、判定を行わないように制御し、キャラが侵入したときにだけ判定を行うようにします。

 コルーチンメソッドである EatingTarget メソッド内で、食べるアニメの再生、キャラの制御など、一連の制御をすべて実行します。

 このスクリプトを記述する際には、まずは最初に設計の日本語のコメントだけを書いて、プログラムは書かないでおいてください
その後、その日本語を自分なりにロジックとして考えてプログラムに直して処理を記述できるか、挑戦してみてください。


ObstacleFlower.cs

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



6.<TryGetComponent()メソッドとoutキーワード宣言>


 Unity2019.2以降に追加されたメソッドです。処理結果として bool 型で戻り値を返してくれます。
このときの処理結果というのは、指定したコンポーネントの型の取得を行い、それが取得できれば true、取得できなければ false が戻ります

 またoutキーワードによる宣言がありますので、trueの場合には必ず、このoutの後に宣言した変数内に型が代入されます。
 outキーワード宣言を行うと、outを付けた引数で指定した変数はメソッド内で必ず結果が入ることが保証されるものです

 // col.gameObject(つまり、Penguin ゲームオブジェクト)に対して、TryGetComponent メソッドを実行し、PlayerController クラスの情報を取得できるか判定する
  if (col.gameObject.TryGetComponent(out PlayerController player)) {

      // PlayerController クラスを取得出来た場合のみ、この if 文の中の処理が実行される
      // その場合、player 変数を利用することで PlayerController クラスを参照できる

      // 食べる
      StartCoroutine(EatingTarget(player));
  }

 今回はこのような処理として利用しています。
Collider 情報から gameObject(つまりキャラです)へとアクセスし、その gameObject に対して TryGetComponent メソッドを実行しています

 out キーワードの後には PlayerController 型と player という変数を用意しておきます。

 もしもこの TryGetComponent の結果が true であるならば、out として用意した player 変数に PlayerController コンポーネントの情報が代入された上で、if文内に処理が入ります
また if 文内の間はこの player 変数が使用できることになります。(player 変数のスコープが if 文ブロック内であるためです)

 TryGetComponent メソッドの結果が false の場合には PlayerController コンポーネントの取得ができなかったため false が結果として戻り、この if 文は処理されないままで終了します

 なおTryGetComponentメソッドには複数の書式があります。こちらは下記のリファレンスを参照してください。


参考サイト
Unity公式スクリプトリファレンス
Component.TryGetComponent
https://docs.unity3d.com/ScriptReference/Component...


7.<DORotate メソッドの RotateMode オプション>


 DOTween の扱う DORotate メソッドには、第3引数として RotateMode という enum の設定値があります。
オプション設定のため、指定しない場合、自動的に RotateMode.Fast が設定されるようになっています。

 今回は食べられて吐き出されたキャラの回転の制御について、 RotateMode のうち、FastBeyond360 を設定しています。

  // キャラを回転させる
  player.transform.DORotate(new Vector3(180, 0, 1080), 0.5f, RotateMode.FastBeyond360);

 この設定を行って回転角度を 360 以上に設定することにより、360度を超えて回転を行うようになります。
今回の場合、Z 軸の回転角度を 1080 に設定していますので、(360 * 3) で3回転するようになります。


8.ObstacleFlower ゲームオブジェクトに ObstacleFlower スクリプトをアタッチする


 作成した ObstacleFlower スクリプトをヒエラルキーにある ObstacleFlower ゲームオブジェクトにドラッグアンドドロップしてアタッチしてください。
ObstacleFlower ゲームオブジェクトのインスペクターより、スクリプトが正常にアタッチされているかを確認します。インスペクターから設定する値はありません。


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



 障害物用のゲームオブジェクトの作成はこれで完了です。




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


 すべての手順が完成しましたので、適宜な位置に ObstacleFlower のゲームオブジェクトを移動させてゲームを実行し、キャラを侵入させてください。
このとき、花輪を1〜数個くぐってから侵入するように配置をすると、スコアが半分になる確認も一緒に行えます。

 コライダーの範囲内であれば侵入判定が発生し、キャラを口の中の中央へ移動し、食べるアニメ再生が再生されます。
その後、キャラを上空へと吐き出して、ObstacleFlower のゲームオブジェクトは徐々に小さくなって破壊されていれば制御成功です。


<実装動画 Sceneビュー 食べて吐き出して、小さくなり消える>
https://gyazo.com/0b804045bc186087889e1ec4038168ff


<実装動画 Gameビュー(食べられるとキャラが口の中の中央に移動する)>
https://gyazo.com/990e5eb2a250ceab70f8dc3409496ba5



 画面に表示されているスコアの値が、侵入前の値の半分になっていることを確認してください。


<実装動画 食べられるとペナルティとしてスコアが半分になる>
https://gyazo.com/5e5214644be4085062cd87e05b9e826f



 また食べられる間は落下が停止し、移動の操作が行えないことも確認してください。


<実装動画 食べられている間は移動できない>
https://gyazo.com/36d0c0083358b56d82876184f4ed8055


10.ObstacleFlower ゲームオブジェクトをプレファブする


 挙動に問題がなければ、今後、ObstacleFlower のゲームオブジェクトを増やしたり、スクリプトから生成させることも念頭に入れて
ObstacleFlower ゲームオブジェクトをプレファブにしておきます。

 Prefabs フォルダに ObstacleFlower ゲームオブジェクトをドラッグアンドドロップしてプレファブにします。
その後、プレファブの ObstacleFlower ゲームオブジェクトを選択して、インスペクターの一番上にある Opne Prefab ボタンを押してプレファブ編集モードにします。

 Transform の Position の値をすべて (0, 0, 0)にしておいてください
このとき、Transform コンポーネントの Reset をかけると、設定してある Scale の値も 1 に戻ってしまうため、Position の値だけを 0 にしてください。


ObstacleFlower ゲームオブジェクト プレファブにした際のインスペクター画像



ObstacleFlower ゲームオブジェクト 編集モード画像


 ObstacleFlower ゲームオブジェクトのプレファブを、自由に設置してみてください。
その場合、フォルダ役のゲームオブジェクトを作成し、その中に ObstacleFlower ゲームオブジェクトを子オブジェクトとしていれて管理するといいでしょう。

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

 => 次は 発展3 ー高度計用のアイコンの実装ー です。


11.<応用 SEを鳴らす>


 障害物に食べられた際に、SEを鳴らすようにしてみましょう

 食べたタイミング、吐き出すタイミングに合わせて、別々のSEを鳴らすようにすると演出として効果的です。
ロジックを考えて実装してみてください。

コメントをかく


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

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

Menu



プログラムの基礎学習

コード練習

技術/知識(実装例)

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

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

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

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

レースゲーム(抜粋)

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

3D脱出ゲーム(抜粋)

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

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

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

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

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

VideoPlayer イベント連動の実装例

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

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

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

private



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

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