UnityでFPSをつくる その4-1 [ カメラの設定 ]

2020年5月27日

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

No.146

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

No.147

FPS(一人称視点)ゲームなので、人の眼を再現するよう Playerオブジェクトの前面上方にカメラを配置しました。

次に、Player の移動にカメラも追従するようにします。
Hierarchyウィンドウの Main Camera を Player の位置にドラッグ&ドロップしてください。

No.148

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

No.149

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

No.150

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

実行して動かしてみましょう。

No.151

カメラが追従するようになりました。

しかし、カメラが映し出す画面(GameView)はずっと同じままです。

No.152

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

No.153

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

Nol.154

表示されていた青空(Skybox)が Solid Color で指定した黒一色になります。

③と④ではカメラが映し出す範囲の始点と終点を設定しています。

No.155

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

No.156

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

No.157

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

上書き保存して実行します。

No.158

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

No.159

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

No.160
No.161

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

No.162
No.163

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

No.164

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

No.165
No.166

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

No.167

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

No.168

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

No.169

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

No.170

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

No.171

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

No.172

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

No.173

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

No.174

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コンポーネント各項目の値を取得する書き方です。

No.175

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

FPS

Posted by kenji