はじめに
こんにちは、azarashin です。 ゲームで重要な要素の一つにカメラの概念が挙げられます。 カメラの概念は、例えばキャラクターを動かしたときにそのキャラの動きに合わせて表示する範囲を変化させたり、 FPSのようなゲームで主人公の視点から見た風景を再現したりするのに利用されます。 本記事ではこのカメラの概念について紹介していきます。
2Dと3D の使い分け
まず、カメラには大きく分けて2つの種類があります。
カメラの種類 | 特徴 |
---|---|
orthographic | 遠近感がなく、遠くと近くとで被写体の見た目の大きさが変化しない。2Dゲームでよく用いられる。 |
perspective | 遠近感があり、遠くの被写体ほど小さく、近くの被写体ほどと大きく見た目の大きさが変化する。3Dゲームでよく用いられる。 |
これらを切り替えるには、まずHierarchy からMain Camera を選択します(初期状態で配置されています)。
続いてInspector からProjection の項目を選択すると、orthographic かperspective かを切り替えることができます。
orthographic の場合(2Dゲーム向け)
orthographic の視界のイメージは下図のようになります。
orthographic の場合、長方形のような視界になり、カメラに近くても遠くても視界の範囲が変化しません。 そのため、被写体の実際の大きさが同じであれば、下図のようにカメラからの距離に関わらず同じ大きさで表示されます。
左側の青い箱3つは右側の赤い箱3つよりもカメラに近いにも関わらず、同じ大きさで表示されていることがわかります。
このカメラにはいくつかのパラメータを設定することができます。2D ゲーム向けであるorthographic の場合、よく使うパラメータはBackground(背景色)とSize(範囲)でしょう。
Background の色を変更すると、被写体の背景の色が変化します。 また、Size を変化させると視界の範囲が変化します。Size を大きくすると視界が広くなり、相対的に被写体の見た目の大きさが小さくなることが確認できます。
perspective の場合(3Dゲーム向け)
perspective の視界のイメージは下図のようになります。
perspective の場合、三角形のような視界になり、カメラからの距離に応じて視界の範囲が変化します。 そのため、被写体の実際の大きさが同じであっても、下図のようにカメラからの距離に応じて異なる大きさで表示されます。
左側の青い箱3つは右側の赤い箱3つよりもカメラに近いため、赤い箱3つよりも大きく表示されていることがわかります。
このカメラにはいくつかのパラメータを設定することができます。 3D ゲーム向けであるperspective の場合、よく使うパラメータはClear Flags(背景の種類)とBackground(背景色)、そしてField of View(視野角)でしょう。
Background の色を変更すると、被写体の背景の色が変化します。 また、Field of View を変化させると視界の範囲が変化します。Field of View を大きくすると視界が広くなり、相対的に被写体の見た目の大きさが小さくなることが確認できます。
perspective タイプのカメラの場合、カメラを左右に動かすと遠くの被写体と近くの被写体とで位置の変化量が異なるのも特徴で、 実際の3次元空間におけるカメラの風景を再現することが可能です。
カメラワークについて
orthographic とperspective の両方に共通して言えることですが、Inspector の欄にTransform が存在しています。
つまり、その他のGameObject と同様にカメラの位置や向き姿勢をUnity エディタやスクリプトを用いて調整・制御することが可能です。
少し長いですが、下記のようなスクリプトを記述し、Main Camera にアタッチします。
using System.Collections; using System.Collections.Generic; using UnityEngine; [RequireComponent(typeof(Camera))] // このスクリプトがアタッチされたGameObject にはCamera コンポーネントが必要である public class SampleObject : MonoBehaviour { // Start is called before the first frame update void Start() { StartCoroutine(CoStartCameraWork()); // カメラワークの演出を開始する。 } // Update is called once per frame void Update() { } // カメラワークを順に実行していく。 IEnumerator CoStartCameraWork() { float remainingTime; // 演出の残り時間 float maxTime; // 演出のトータル時間 maxTime = 5.0f; remainingTime = maxTime; // 左右に移動する while(remainingTime > 0.0f) { float amp = 3.0f; transform.position = new Vector3(Mathf.Sin(Mathf.PI * 2.0f * remainingTime / maxTime) * amp, 0.0f, 0.0f); remainingTime -= Time.deltaTime; yield return null; // 1フレームレンダリングし終わったら続きの処理を実行する } maxTime = 5.0f; remainingTime = maxTime; // 視線軸方向に回転する while (remainingTime > 0.0f) { float shakeAngle = 30.0f; transform.rotation = Quaternion.Euler(0.0f, 0.0f, Mathf.Sin(Mathf.PI * 2.0f * remainingTime / maxTime) * shakeAngle); remainingTime -= Time.deltaTime; yield return null; // 1フレームレンダリングし終わったら続きの処理を実行する } Camera camera = GetComponent<Camera>(); // 対象のGameObject に付与されているCamera コンポーネントを取得する。 maxTime = 5.0f; remainingTime = maxTime; // 視界を変化させる while (remainingTime > 0.0f) { float maxAngle = 90.0f; float minAngle = 30.0f; float progress = 1.0f - remainingTime / maxTime; camera.fieldOfView = progress * (maxAngle - minAngle) + minAngle; remainingTime -= Time.deltaTime; yield return null; // 1フレームレンダリングし終わったら続きの処理を実行する } } }
これをMain Camera にアタッチしてプログラムの再生を開始すると以下のようなアニメーションが実行されます。
おわりに
ゲーム開発においてカメラワークは重要な要素の一つです。 カメラの動きをキャラクターと連動させるだけでなく、Field of view を使いこなすことで 実際のカメラのようにズーム倍率を変化させるような演出も可能になります。
なお、今回は説明しませんでしたが、 被写体の背景には単純な色だけでなく、画像を割り当てることもできます。 Main Camera のInspector 欄からClear Flags を選択し、Solid Color (塗りつぶし)からSkybox に変更します。
Skybox は自作することもできますが、下記のようなアセットストアからフリーのSkybox を調達することも可能です。
本格的な3Dゲームを制作することになってきたら、Skybox の活用にも挑戦してみてはいかがでしょうか?