はじめに
筆者が市販のステルスアクションゲームを遊んでいて違和感を覚えていたことがあります。 それは、敵に見つかった時に「なぜ見つかったのか?」「本当に敵に見つかったのか?」ということに対してピンとこなかったことです。 このような違和感を解消するべく、筆者がSteamで販売した「盗賊少女」には主人公や敵の視点で見た風景をプレイヤーに伝えるような工夫を取り入れました。
そこで、本記事ではUnityでメインカメラとは別視点の映像を表示する手法についてご紹介いたします。
レンダーテクスチャについて
メインカメラとは別視点の映像を表示するには、Unity のレンダーテクスチャというものを使用します。 レンダーテクスチャを利用するには主に以下の手順を実施していきます。
- 別視点カメラ設置
- レンダーテクスチャ作成
- カメラ出力先設定
- レンダーテクスチャの表示
本記事ではまずUnityの通常のテクスチャの描画の仕組みについて触れ、 その後上記のレンダーテクスチャを用いた描画の仕組みについて説明していきたいと思います。
Unityの通常のテクスチャの描画の仕組み
Unity をはじめとする3DCGエンジンではメッシュ・テクスチャ・マテリアルを使ってレンダリングを行い、その結果が画面へ出力されるのが一般的です。 それぞれの役割は以下の通りです。
- メッシュ
- テクスチャ
- マテリアル
メッシュ・テクスチャ・マテリアルの一般的な関係を図で示すと下図のようになります。
レンダーテクスチャを使った描画の仕組み
ファイルから読み込んだ画像ではなく、主人公・敵の視点からみた風景を画面に表示する場合、レンダリング処理の流れは下図のようになります。
この流れにおける最大の特徴は、ファイルから取得したテクスチャを使うのではなく、一度レンダリングした結果をテクスチャ領域に書き込み、 レンダーテクスチャ(RenderTexture)として他の視点でのレンダリングに再利用していることです。
次節以降、レンダリング処理の流れについて細かく説明していきます。
別視点のカメラを設置する
通常、シーン上に配置するカメラは一つだけで、新たにシーンを作成すると自動的にカメラが設置されるのですが、今回は主人公・敵の視点から見た風景を画面に表示するため、主人公・敵の頭の位置に新しくカメラを設置します。
まず、ヒエラルキー上で右クリック→Camera を選択します。
するとカメラコンポーネントが付与されたオブジェクト追加されます(主観カメラオブジェクトと呼びます)。
この主観カメラオブジェクトの位置・向きが主人公や敵の視点に一致するようにスクリプトを書きます。 Camera クラスのfieldOfView メンバを設定すると、敵の視野の広さも反映させることができるようになります。 視野が狭いとカメラをズームして拡大したような見た目になります。
private Camera _cameraView; // 主観カメラオブジェクト private Transform _currentEye; // 主人公または敵のTransform を割り当てる(状況に応じて使い分ける) private float _fieldOfView = 90; // 視界の広さ void Update() { _cameraView.transform.position = _currentEye.position; _cameraView.transform.rotation = _currentEye.rotation; _cameraView.fieldOfView = _fieldOfView; }
すると、主観カメラが主人公や敵の視点に一致するようになります。
これで主観カメラが追加されたわけですが、この状態だと今まで使用していたカメラで映していた風景が画面から消え、主観カメラでの風景が画面に表示されてしまいます。 この状態を「今まで使用していたカメラで映した風景を画面に表示し、右下隅に主観カメラで映した風景を表示する」という状態にするためにいくつか変更を施していきます。
レンダーテクスチャの作成
まず、主観カメラでの風景をレンダリングした結果をテクスチャ領域に書き込む必要があります。このテクスチャは特殊なテクスチャで、レンダーテクスチャ(RenderTexture)と呼ばれます。 レンダーテクスチャを作成するには、Project 欄の適当な場所で右クリック→Create→Render Texture と選択します。
レンダーテクスチャを生成するとInspector にて各種パラメータを設定できるようになりますので、 まずはテクスチャの解像度だけでも設定しておきましょう。 解像度の値は2のべき乗にしておきましょう(2のべき乗以外にするとプラットフォームによっては正常に表示されないことがあります)。
2のべき乗は512(2の9乗)や1024(2の10乗)、2048(2の11乗)といった値です。 解像度は大きくするとより精細に表現できますが、メモリをその分大きく消費します。必要以上に解像度が大きくならないよう、丁度よい値を検討しましょう。
今回は画面の右下隅の部分領域に表示することを考えると、 画面全体の高さが1080の場合であればレンダーテクスチャの高さは512 もあれば十分でしょう。
以上の処理が正しく実施されていれば、アプリ再生時に主観カメラの風景がInspector で確認できるようになります。
カメラの出力先をテクスチャに変える
Inspector より主観カメラのCamera コンポーネントを編集します。Camera コンポーネントの中にTarget Texture という欄がありますので、ここに先ほど作成したレンダーテクスチャを割り当てます。
レンダーテクスチャを画面に表示する
今回は画面の右下に画像を表示するので、UI要素を新しく追加します。 ヒエラルキーツリーのCanvas オブジェクトの下にUI → Raw Image を追加してください。 (Canvas がなければUI → Canvas を追加してください)。
そして、追加されたRaw Image に対してInspector を開き、Raw ImageコンポーネントのTexture 欄に先ほど作成したRender Texture を割り当ててください。
以上のように設定することで、カメラの風景 → Render Texture → UI部品(Raw Image)という流れでカメラの風景をUI部品に反映させることができるようになります。
レンダーテクスチャの活用例
冒頭でもお話ししたように、筆者がSteamで販売した「盗賊少女」には主人公や敵の視点で見た風景をプレイヤーに伝えるような工夫を取り入れており、 レンダーテクスチャを活用してメインカメラとは別視点の映像を画面に表示しています。
例えば、敵の視点から見た風景をレンダーテクスチャに書き込み、外枠などと合成すると下図のようになります。
画面全体としては下図のようになります。
このように、レンダーテクスチャを使うとメインカメラで映したフィールドの風景にメインカメラとは別視点(敵視点)の画面を表示することができるのです。
この他にもレンダーテクスチャを使うと以下のような応用が可能です。 是非挑戦してみてください。
- 鏡の表現
- 協力プレイ時の画面分割
- レースゲームのバックミラー
- ライブモニターに映るキャラクター
おわりに
本記事では主人公や敵の視点で見た風景を画面の一部分に表示し、確認できるようにする事例について紹介しました。 カメラワークはゲームにおける工夫ポイントの一つですので、いろいろと試してみてください。 また、レンダーテクスチャの中身はUI だけでなく、他のメッシュに張り付けることができます。さらにマテリアルにより加工して演出の幅を広げる等、様々な応用が可能です。 まずはレンダーテクスチャについて簡単なデモを作成することを最初のステップとし、徐々にいろいろな工夫に挑戦してみてください。