i-school - 3Dダイビングゲーム 手順5
 以下の内容で順番に実装を進めていきます。

 この手順では、カメラがキャラクターを追従するように制御処理を実装していきます。

手順5 −カメラの追従処理の実装−
 7.スクリプトを使って、カメラがキャラを追従するように制御する



新しく学習する内容


 ・SerializeField属性
 ・アタッチとアサインについて


7.スクリプトを使って、カメラがキャラを追従するように制御する

1.設計


 ゲーム画面は、Main Camera コンポーネントにアタッチされている Camera コンポーネントが映している画面になります。

 ゲーム開始に合わせてキャラは落下を開始しますが、カメラの位置は変更されません。そのため、ゲーム画面にはキャラが映りませんし、
キャラの移動に合わせて自動的に変更されるようにはなりません。

 こういったゲームオブジェクトの間での制御が必要になる場合、多くはスクリプトを利用して、ゲームオブジェクトやコンポーネントの制御を行います

 今回は、カメラにキャラを追従させるためのプログラムを組み、それをスクリプトに記述します。

 カメラがどのようにキャラを追従するかですが、カメラのゲームオブジェクトの位置をスクリプトによって制御することで実現します。

 ゲームが始まる際のお互いの位置を元に、どの位の距離離れているかを補正値として用意します。
これはいわば、キャラとカメラの差分値です。そのため、キャラが落下を行って下方向へ移動する場合、この差分値分の距離だけ離れて追従するようにすれば、
カメラも一緒に下方向に移動しつつ、ゲーム開始時からの距離を保ったままキャラを追従するように制御を行うことが出来ます


<実装動画 Scene ビューも見ると、常に一定の距離を保ってカメラがキャラを追従している>
https://gyazo.com/91f4a732f1288d7aaf25800c3cfc81ab

 
 まずは最初に、カメラの位置を設定します。この位置とキャラの位置とが補正値となりますので重要な情報です。
その後、スクリプトを作成して、カメラのゲームオブジェクトにアタッチして設定を行います。


2.Main Camera ゲームオブジェクトの位置を調整する


 Main Camera ゲームオブジェクトの位置を調整して、Penguin ゲームオブジェクトを映す位置に移動させます。

 Sceneビューでゲームオブジェクトの位置を操作しながら、Gameビュー、あるいは Sceneビューに表示されるCameraビューを見ながら操作を行います。
インスペクター画像の Position や Rotation の位置を参考にしてください。
 基本的には位置については、Penguin ゲームオブジェクト の Position の Y + 4 前後が見やすい位置です。
例えば現在のPenguin ゲームオブジェクトの Position.y が 5 であるならば、Main Camera ゲームオブジェクトの Position.y は 9 です。


<参考動画 カメラの操作>
https://gyazo.com/b1a5bc5dad529bd0add51274079f9a57


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



Sceneビュー



Gameビュー



3.CameraController スクリプトを作成する


 新しいスクリプトを作成します。スクリプトを格納するためのフォルダを用意して、その中に作成します。

 Projectの上で右クリックをしてメニューを開き、Create => Folder を選択して、新しいフォルダを作成します。
名前を Scripts に変更します。

 Scripts フォルダの中で右クリックをしてメニューを開き、Create => C# Script を選択します。
名前を Camera Controller に変更して、ダブルクリックを行い、スクリプトを編集する Visual Studio エディターを開きます。


フォルダ構成




 宣言フィールドでは2つの変数を新しく宣言して用意します。
1つはカメラが追従する対象を設定するための GameObject 型の playerObj 変数です。
こちらに設定を行ったゲームオブジェクトをカメラが追従する制御を行っています。

 もう1つは Vector3 型の offset 変数です。カメラと追従する対象との一定の距離を設定するための値です。
カメラは常にこの値の分だけ離れて対象を追従するように制御しています。

 メソッドは2つ用意します。作成時に作られているメソッドのみで処理を制御できます。

 Start メソッドでは、offest 変数に、対象とカメラとの距離を計算して差分を算出し、その値を代入しておきます。
この値がゲームスタート時のカメラと対象(ペンギン)の離れている距離になります。

 Update メソッドでは、この offset 変数の値を利用して、カメラの位置を常にペンギンから一定の距離だけ離れて移動させることにより、
カメラがペンギンを追従するように制御を行います。

 また追従する処理の前に、if 文で追従する対象が設定されているかどうかの確認を入れています。
なぜなら Update メソッドの処理は常に動いている処理であるため、万が一、playerObj 変数の値が空(追従対象の登録がない場合)には
エラーになってゲームが停止してしまいます。それを未然に防ぐために、追従処理を行うための前提条件として、追従する対象がいるかどうかのチェックを行っています

 処理を記述する際には、どんな変数があってどのように利用されているのかを確認しながら書くように心がけてください。


CameraController.cs

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



4.<SerializeField属性>


 変数の宣言に合わせて宣言できる、属性情報と呼ばれるものの1つです。変数の宣言の前に [ ] 付きで書かれた内容が属性情報となります。

 今回利用している属性は SerializeField (シリアライズ・フィールド)という属性情報です。この機能は、インスペクター上に宣言している変数名を表示させる、というものです。

 主に private 修飾子とセットで用いられ、アサインをインスペクター上で可能にするものの、変数の参照先が外部のスクリプトにない(publicの必要がない)場合に利用します。
たとえばButtonコンポーネントやTextコンポーネントといった、アサインはするものの、その変数の利用先が他のスクリプトにはないようなもの、には利用しやすいです。

 今回はヒエラルキーにある GameObject 型の情報をアサインできるように宣言しています。


5.Main Camera ゲームオブジェクトに Camera Controller スクリプトをアタッチする


 スクリプトを作成したらセーブを行います。Visual Studio でのセーブのショートカットは shift + ctrl + s キーです

 スクリプトはゲームオブジェクトにアタッチしないと実行されません。今回は Main Camera ゲームオブジェクト用に作成したスクリプトですので
Main Camera ゲームオブジェクトにアタッチを行います。

 Scripts フォルダにある Camera Controller スクリプトをドラッグして、ヒエラルキーにある Main Camera ゲームオブジェクトの上でドロップします。
Main Camera ゲームオブジェクトをインスペクターで確認して、アタッチされているかを確認してください。
もしもアタッチ出来ていなければもう一度、ドラッグアンドドロップしてアタッチしてください。


<手順動画 アタッチ>
https://gyazo.com/26ab78130aa085fb174408e0aaee4353


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



6.Main Camera ゲームオブジェクトに Camera Controller スクリプトのアサイン情報に、Penguin ゲームオブジェクトをドラッグアンドドロップしてアサインする


 Main Camera ゲームオブジェクトにアタッチされた Camera Controller スクリプトを確認します。

 SerializeField属性で宣言しているため、private 修飾子の playerObj 変数がインスペクター上に見えるようになっています。
ここに対象となるゲームオブジェクトをアサインすれば、それで変数への代入処理が完了します。
そのため、スクリプト内でFindメソッドなどの、ゲームオブジェクトを探してきて変数に代入する処理は不要になります。

 playerObj 変数は GameObject 型です。そのため、ヒエラルキーにあるすべてのゲームオブジェクトはアサインの対象になります。
今回は、カメラの追従対象となるべきゲームオブジェクトをアサイン情報として登録する必要がありますので、
ヒエラルキーにある Penguin ゲームオブジェクトをドラッグし、playerObj 変数の上にドロップしてアサインします


<手順動画 アサイン>
https://gyazo.com/c8ff760295e9ec1c9e7cb04fc7ad620f


Main Camera ゲームオブジェクト アサイン後のインスペクター画像



7.<アタッチとアサインについて>


 アタッチアサインという単語があります。これらは似ている言葉ですが、役割は異なります。
正確に把握していないと、先々でつまづいてしまう原因になりますので、しっかりと意味を捉えておきましょう。

 アタッチとは、作成したスクリプト・ファイルやコンポーネントをゲームオブジェクトにドラッグアンドドロップして追加する動作のことです。


<アタッチ>
https://gyazo.com/31b0fb67add402eb9b445c52a45a39b2


 アサインとは、ヒエラルキーにあるゲームオブジェクトをドラッグアンドドロップして
別のゲームオブジェクトのインスペクターに表示されている変数の場所に、そのゲームオブジェクトが持つ情報を登録(代入)する、という動作のことです。


<アサイン>
https://gyazo.com/c8ff760295e9ec1c9e7cb04fc7ad620f


 勘違いすやすいのは、スクリプト・ファイル自体をドラッグアンドドロップして、アサインすることはできません


<間違い>
https://gyazo.com/95c74d487fbaad31e0af1695b9766dfa


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


 ゲームを実行して、Gameビューにおいて、カメラがキャラを追従するようになっているかを確認します。


<実行動画>
https://gyazo.com/86067d0d136df3958636449fbb3b237a


 無事に追従している場合には、Penguin ゲームオブジェクトの位置を高い位置に変更して試してみます。

 Penguin ゲームオブジェクトの Transform の Position の Y を 20 に、Main Camera ゲームオブジェクトのTransform の Position の Y を 24 にそれぞれ変更します。
そしてゲームを実行してみましょう。


Penguin、Main Camera ゲームオブジェクトの各インスペクター画像



<実行動画 高い位置から追従する>
https://gyazo.com/91f4a732f1288d7aaf25800c3cfc81ab


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

 => 次は 手順6 −キャラの移動の実装− です。