UnityでFPSをつくる その4-1 [ カメラの設定 ]
カメラの設定をしていきます。
Sceneビューで右方向からの視点にした後、Main Camera を選択して Transform の値をリセットしてください。

Transform Position Y を「1」, Z を「0.5」にしてください。

FPS(一人称視点)ゲームなので、人の眼を再現するよう Playerオブジェクトの前面上方にカメラを配置しました。
次に、Player の移動にカメラも追従するようにします。
Hierarchyウィンドウの Main Camera を Player の位置にドラッグ&ドロップしてください。

Player の下の階層に Main Camera が表示されました。
Player が親オブジェクトになり、Main Camera が子オブジェクトとして扱われます。
Main Camera の Transform Position を見てください。

Player の子になる前は「1」だった値が「0.5」になりました。
これは、子になることで、絶対値(ワールド座標)が親からの相対値(ローカル座標)に変化した為です。

絶対値は Scene の中心を基準(0, 0, 0)とする為、Player の子になる前(自身が親の状態)の Main Camera は「Scene から Y 方向+1に位置している」と表示されていました。
Player の子になることで、Player の中心を基準(0, 0, 0)とする為、「Player から Y 方向+0.5に位置している」に表示が変わりました。
実行して動かしてみましょう。

カメラが追従するようになりました。
しかし、カメラが映し出す画面(GameView)はずっと同じままです。

カメラの設定を変えて、この状態を解消します。
Main Camera の Camera コンポーネントの項目を以下のように変更してください。

➀と②は、カメラに何も映っていない時、代わりに描画するものを設定しています。
➀を Solid Color にした場合、Background で指定した色が、何も映っていない部分の代わりに描画されます。
下図は、他の項目を初期設定のまま①と②のみ変更した状態です。

表示されていた青空(Skybox)が Solid Color で指定した黒一色になります。
③と④ではカメラが映し出す範囲の始点と終点を設定しています。

初期設定では Far の値が「1000」だった為に壁まで届かず、何もない空間に Skybox や SolidColor が表示されていたんですね。

Far の値を「12000」まで大きくしたことで、描画範囲に壁が収まって映りました。

次に、マウスの動きに応じてカメラを上下左右に回転させます。
以下のスクリプトを PlayerMove にコピペしてください。
上書き保存して実行します。

この動きをどう実装しているのか、追加したスクリプトの説明をしていきます。

16行目、キー入力の戻り値を float 型変数で取得したように、マウスの XY 座標移動量を float 型変数で取得する為に宣言しています。


18行目、視点を上下に移動する際、カメラだけを回転させたいので、取得用の変数を宣言しています。


20行目、キー入力の時と同様に、マウスでも許可を出す役割のbool型変数を宣言しています。

22行目、カメラの Transform コンポーネント取得用の Transform 型変数を宣言しています。


30行目、Main Camera オブジェクトの Transform コンポーネントを取得しています。

player オブジェクトから Rigidbody コンポーネントを取得する時は下図のように書きましたが、今回 Main Camera からTransform コンポーネントを取得する書き方と大分違いがあります。

これはどちらも省略した書き方をしている為で、省略しない場合は下図のように書きます。

ここで一つ疑問が、GetComponent<Transform>() を transform に書き換えるように GetComponent<Rigidbody>() を rigidbody と書き換えできないのか?
それは、できないんです。
Transformコンポーネントは特別なコンポーネントで、シーン内に配置された全てのオブジェクトが持っています。
シーン内に配置=位置情報を持つわけなので、他のコンポーネントと違い、取り外したりすることができません。

最初から付いていて取り外すこともできないので、GetComponent<>() で探し出す必要が無いわけです。
又、Transformコンポーネントの位置、回転、大きさなどは頻繁に使用される為、高速にアクセスできるよう専用の内部関数が用意されているので、他のコンポーネントとは違う書き方で呼び出せるようになっています。

32行目では、取得したメインカメラの Transform コンポーネントから、親であるプレイヤーオブジェクトからの相対角度X を取得しています。

「localEulerAngles.x? localRotation.xでX回転角を取得できないの??」と思った方がいるかもしれませんが、localRotation.x で取得できる値は上図で表示されている値と異なります。
確認してみます。Inspectorウィンドウのタブメニューから「Debug」を選択します。

Debugモードにすることで各項目が内部的に、どういった数値で扱われているのかを見る事ができます。
Transform の Local Rotation を見てください。

X, Y, Z に W……W??? そうなんです、Unityの内部ではX, Y, Zの回転の計算に4つの値を使っています。
これは Quaternion(クォータニオン)と呼ばれるもので、3次元の回転の計算を3つの値(X, Y, Z)で行うより、4つの値(X, Y, Z, W)で行ったほうが計算量が少なくなって高速に動作する為です。
しかし、この方法で回転値を扱うのは直感的でない為、非常に理解しづらいです。
そこで、多少の速度を犠牲にしても localEulerAngles(親から見た相対的なオイラー角の回転値を取得する変数)を使って、Quaternion(クォータニオン) 型からVector3型のEulerAngles(オイラー角度)へ変換し、 Inspector に表示されている回転角(オイラー角)を取得しています。
以下、Inspector に表示される Transformコンポーネント各項目の値を取得する書き方です。

だいぶ長くなってきたので続きは次回にしたいと思います。おつかれさまでした!