見下ろし型やクラフト系ゲームのカメラはどう実装する?『Universal Camera』を使って柔軟なカメラ動作を実現しよう

2022.11.28
注目記事ゲームづくりの知識チュートリアルしくみをつくる見た目を良くするアセットレビュー
この記事をシェア!
Twitter Facebook LINE B!
Twitter Facebook LINE B!

見下ろし型ゲームのようにプレイヤーの視点とキャラクターを切り離したい、そもそもキャラクターがいないのでプレイヤーの視点そのものを自在に動かしたい、そんな場合に有効なのが「ポーン」です。

Universal Camera』というアセットは自由なカメラ動作を持ったポーン派生クラスを作成できるアセットであり、柔軟にゲーム制作をサポートしてくれます。今回はこれを使ってのカメラ動作の実装とポーンへの理解を深めていきましょう。

TEXT / wvigler
EDIT / 神山 大輝

目次

この記事はUnreal Engine バージョン5.0.3を利用して書かれています。

今回使用するアセットとテンプレートを紹介

今回サンプルとして用いるUniversal Camera』は、さまざまなカメラの動きをサポートするためのポーン派生クラスを提供するコードプラグインです。

付属するポーン派生クラスを利用することで、ゲーム内で使用されるさまざまなカメラワークを柔軟に実装することができるようになります。また、ゲームにおけるさまざまなシチュエーションに対応できるよう、設定も細かく行えるようになっています。ゲーム制作の自由度をあまり妨げないため使い勝手がよく、それでいて痒いところに手が届くアセットです。

Universal Cameraが役立つ場面

Universal Cameraはカメラワークを提供するプラグインですが、エンジン内の『サードパーソン』などのテンプレートにもデフォルトでカメラ操作の機能は存在しているため、このアセットがどのような場面で役に立つのか想像しにくいしれません。

サードパーソンではメインとなるキャラクターが存在し、それに追加される形でSpring Armというカメラ操作のためのアームの役割をするコンポーネントがあり、さらにその先にゲーム内視点となるカメラが取り付けられています。

メインキャラクターにコンポーネントとしてカメラ機能を実装することで、カメラがメインキャラクターを常に追従することになる

このように、キャラクターに直接カメラのコンポーネントを持たせるというやり方は常にメインキャラクターを追いかける形になるため、小さなプロジェクトの場合は有効です。しかし、実際にゲームを作っていくと「ただキャラクターを追従するだけではなく、もっと自由度を持たせ、プレイヤーの視点をキャラクターから独立して動かしたい」といった場面も発生します。

例えば対戦格闘ゲームなどを見てみましょう。メインとなる自分が操作するキャラクターはもちろん存在していますが、その視点は操作するキャラクターを常に追従しているわけではなく、お互いのキャラクターの中心あたりを映していることが多いです。

また、街作りなどを主題とするシミュレーションゲームなどはそもそもこの構造の「核」になるメインキャラクターというもの自体が存在しません。

キャラクターを追従しないカメラ機能を作りたい場合、Unreal Engineではいくつか手段があります。汎用性が高い手段の1つとして、カメラをキャラクターではなく『ポーン』に実装し、キャラクターの動作とカメラの操作を切り離すという方法があります。

ポーンはブループリントの一種で、キャラクター同様にプレイヤーからの入力を受け取ることができます。しかし、キャラクター特有の物理を含む移動動作やスケルタルメッシュ、アニメーションに関する機能などは実装されておらず、シンプルな内容になっています。

キャラクターにコンポーネントとしてカメラが追従している場合、この2つを切り離すのは少々難しい

ポーンを利用することでキャラクターとカメラの操作を切り離せるので自由度が上がり、簡単に切り離せるようになる

また、この方法にはもう1つの利点があります。ここでのポーンは主にカメラの動きのみを管理しているため、同じ仕組みを使って他のキャラクターにカメラの動きを移植することができます。これを使えば、1ゲーム中に同じカメラの動きを使ってさまざまなキャラクターを操作したり、別のゲームにもカメラの動きのみを流用してより簡単にゲームを作ったりすることができるようになるのです。

1つのカメラ管理のポーンから複数のキャラクターを操作することができる

別のゲームに同じ仕組みをコピーすることで、より簡単にゲームを制作することができるようになる

実は、Unreal Engineではキャラクターはポーンの一種です。キャラクターがプレイヤーの入力を受け取れているのは、ポーンがその機能を持っているからです。さらにポーンにはAIに関する機能も備わっています!

ポーンについてよく知ることで、入力の処理やゲーム構造についての理解が進み、より自由度の高い柔軟なゲーム制作が可能になります。

Universal Cameraを使う準備

ここからは実際にプロジェクトを立ち上げて作業をしていきます。まずはUniversal Cameraを使うための準備をしていきましょう。Epic Games LauncherからUniversal Cameraのダウンロードページに移動し、UE5のエンジンにインストールします。

今回は最初に選ぶプロジェクトのテンプレートとして『トップダウン』のテンプレートを使用します。UE5を起動したら、ゲーム→トップダウンを選び、プロジェクトを作成しましょう。

名前は自由に付けて問題ない。ここでは「TestCamera」とした

トップダウンのテンプレートを使ったことがないという場合は、軽くプレイして内容を把握しておくといいでしょう。

『トップダウン』のテンプレートでは、キャラクターの上方の視点から直接クリックで目的地を選びキャラクターを移動させることができる

メインキャラクターのブループリント(コンテンツ\TopDown\Blueprints\BP_TopDownCharacter)を見てみると、サードパーソンなどと同じくカメラ機能はキャラクターにコンポーネントとして付属している

また、Universal Cameraはコードプラグインアセットのためエンジン側でプラグインを有効にする必要があります。プラグイン設定のタブからUniversal Cameraのプラグインを検索してチェックを入れ、再起動しましょう。

プラグインの先頭のチェックボックスをチェックすると、有効化のためにエンジンを再起動するボタンが表示される

これでトップダウンのテンプレートでUniversal Cameraを利用する準備が整いました。続いて、Universal Cameraのブループリントの作成およびセッティングを行い、Universal Cameraがどんなものか実際に動かしてみましょう。

Universal Cameraのセッティングをしよう

まずはコンテンツドロワーを開き、右クリックメニューから「ブループリントクラス」を選択します。

作成する場所はどこでも大丈夫。ここでは分かりやすいようにトップダウンのブループリントが収められている「コンテンツ\TopDown\Blueprints」に作成している。

すると「親クラスを選択」というウィンドウが現れます。下の方にある「すべてのクラス」を選択するとドロップダウンメニューが開き、ブループリントで作成できる全てのクラスが表示されます。

「▼共通」には作成できるブループリントの主な候補が並んでいる。ここではそれらは選択せず、「すべてのクラス」をクリックする

「すべてのクラス」をクリックするとドロップダウンから複数の候補が表示される。検索を利用して必要なクラスを選択しよう

検索欄で「UniversalCamera」と検索し、選択した状態で右下に表示される「選択」をクリックすると新しい「UniversalCamera」のブループリントを作成することができます。

検索窓を活用。Universalで検索すると、Universal Cameraが表示される

新しいブループリントの名前は「BP_UniversalCamera」とした

作成されたブループリントの中身をダブルクリックで見てみましょう。まず、左上の「コンポーネント」タブを確認すると、トップダウンサードパーソンのメインキャラクター同様にSpring Armのコンポーネントが付いています。Universal Cameraはこの先に視点となるカメラを追加して使用します。

Spring Armのコンポーネントを選択した状態で「+追加」を選択すると、ドロップダウンメニューが開きます。「Camera」を選択すると、視点となるカメラのコンポーネントがSpring Armの先端に追加されます。

Universal Cameraのカメラ操作に関するノードはブループリントに内蔵されており、すでに呼び出せる状態ですが、先にプレイヤー入力設定を行います。プロジェクト設定タブから「エンジン」→「インプット」→「バインディング」→「軸マッピング」から入力マッピングを追加します。設定する入力設定の項目がいくつかあるので、以下のように設定してください。

入力マッピング名 入力キー Scale
CameraMoveForward W 1.0
S -1.0
CameraMoveRight D 1.0
A -1.0
CameraRotateYaw E 1.0
Q -1.0
CameraRotatePitch R 1.0
F -1.0
ZoomIn マウスホイール軸 1.0

プロジェクト設定での入力設定が済んだらBP_UniversalCameraのブループリントに戻り、イベントグラフで設定した入力とUniversal Cameraのノードを接続します。繋ぎ方とノードは下の画像を参考にしてください。

入力設定を行うとほとんど同じ名前を持ったノードが2つ呼び出せるようになるので注意!使うのは赤いノードであり、右側の緑のノードは今回使用しない

このままだと初期状態でカメラの角度が0度となり視点が埋まってしまうので、カメラの初期角度を調整します。「クラスのデフォルト」を選択し、右側の「詳細」タブからStarting Position→Override Starting PitchをチェックすればOKです。

これで初期状態ではSpring Armの角度が-65.0度から開始されるようになる

さて、これでBP_UniversalCameraの基本設定は完了しました。設定を終えたBP_UniversalCameraを少しだけマップ上で試してみましょう。

BP_UniversalCameraをドラッグ&ドロップでマップ上に配置し、選択したまま「詳細」タブから「ポーン」カテゴリの「Auto Possess Player」という項目を「Disabled」から「Player 0」に変更します。これで開始時のプレイヤーをデフォルトのキャラクターからBP_UniversalCameraにすることができます。

それでは、プレイを開始してどのようになっているか見てみましょう。プレイ開始すると小さな黄色いデバッグ表示が画面中央に現れます。

WASDでカメラの移動、QとEで黄色い表示を中心にして横回転、RとFで縦に回転、そしてマウスホイールを回転させることでズームインとズームアウトを行うことができます。

無事カメラの動きを実装することができたので、今度はこれを使っていよいよトップダウンのキャラクターとカメラの動きを切り分けましょう。

画面をクリックするとこのような警告表示が出るが、これについては後で解決するため特に問題はない

キャラクターの動きとカメラの動きを分離させよう

キャラクターとカメラの動きの切り分けを理解するために、シンプルなサンプルゲームを作ってみましょう。先ほど作成したBP_UniversalCameraで独立した視点操作をしながら、画面上のクリックした地点にキャラクターが向かうというものです。

「画面上をクリックするとキャラクターがそこに向かう」という仕組みはトップダウンテンプレートにもともと入っていますので、とても簡単に作ることができます。

BP_UniversalCameraをプレイヤーとして指定したため、プレイ開始時にキャラクターがマップ上に現れなくなっています。クリックした場所へと向かうキャラクターのブループリントが必要なので、コンテンツ\TopDown\BlueprintsBP_TopDownCharacterをマップ上にドラッグ&ドロップして配置しましょう。

トップダウンテンプレートでのマウスクリック入力はプレイヤーコントローラーで定義されています。BP_TopDownCharacterと同じフォルダにBP_TopDownControllerというコントローラーのアイコンがあるはずなので、中身を見てみましょう。

イベントグラフにはノードが配置されていますが、ここは「(クリックなどの)入力をどう処理するのか」ということを決めているので、変更する必要はありません。今回変更するのはクリックした先に「誰を動かすのか」です。この処理はイベントグラフ内にあるMove to Hit Locationというノードをダブルクリックすると見ることができます。

ポーンはゲーム中にプレイヤー入力を受け取ることができますが、内部的にはプレイヤーコントローラーからポーンに入力情報が渡されます。このため、プレイヤーコントローラーも入力情報(この場合はマウスでのクリック)を扱うことができます。

Simple Move to Location」の「Controller」のピンが「誰を動かすのか」を決めている場所です。現在「Self」というノードが繋がっていますが、これはプレイヤーコントローラーそのものを指しており、動かす対象として現在のプレイヤーであるBP_UniversalCameraを指定している状態になっています。

「クリックした場所に行く」という動作はAIによる処理になりますが、BP_UniversalCameraはデフォルトではAIによる移動が無効になっています。さっきまでプレイ中に画面をクリックすると警告が出ていたのは、無効になっているはずのAI移動をさせようとしていたためです。

動かす対象を、先ほどマップ上に配置したキャラクターに変更すれば上手く行きそうです。「Get Actor Of Class」というノードを使い、以下のように変更しましょう。

「Get Actor Of Class」の「Actor Class」ピンでBP_TopDownCharacterを指定する

これで、「画面上のどこかがクリックされた場合、マップ上にあるBP_TopDownCharacterを検索して見付け、クリックした場所へと向かわせる」という処理になります。

最後に、前回プレイ開始時に少しズームが近すぎる印象があったので、BP_UniversalCameraのブループリントに戻り、「クラスのデフォルト」で「Override Starting Zoom」を有効にし「Starting Zoom」を「1200.0」に設定しましょう。

ズームの数値は大きいほど遠くなるようになっている

デバッグ表示も同じく「クラスのデフォルト」から設定できる。ついでに表示を切ってしまおう

これでカメラとキャラクターとを分離した、最初のサンプルゲームが完成しました。プレイして動作を確かめてみましょう。視点とキャラクターを別々に動かせれば成功です。

Universal Cameraの基本的な使い方は理解できたでしょうか?このプラグインは、これ以外にもスピード設定などをはじめとした数々の機能や活用法があります。ドキュメント概要解説のビデオもあるので、色々触りながら試してみるのも面白いでしょう。

ほとんどの設定項目は「クラスのデフォルト」で変更できる。「Enabled Features」で各々の機能のON/OFFを切り替えられるので試してみよう

豊富なブループリントノードも用意されており、一時的にカメラをキャラクターなどに追従させることも可能

発展編:Universal Cameraを使って簡単なクラフトゲームを作ろう

最後に、「メインキャラクターが出てこないゲーム」のサンプルとして左クリックでブロックを積めるクラフトゲームを作ってみましょう。さっき作ったものとかなり違うゲームになりますが、全く同じBP_UniversalCameraを利用して作ることができます。カメラの動きをキャラクターから分離する利点の1つです。

マップ上に現在配置されているトップダウンのメインキャラクターは必要ないので、選択してDeleteキーで削除してしまいます。

また、キャラクターを動かさないのでBP_TopDownControllerも必要ありません。「ワールドセッティング」タブから「選択したゲームモード」→「Player Controller Class」を「PlayerController」に変えてしまいましょう。

キャラクターはもう必要ないので、Deleteキーで削除する

「ワールドセッティング」のタブが見当たらない場合は、左上の「ウィンドウ」メニューから追加できる

これ以降、処理は全てBP_UniversalCameraに書いていきます。

さて、一旦この状態でプレイしてみると、先ほどとは違って画面をクリックして操作しようとするとマウスカーソルが消失してしまいます。これは、開始時にプレイヤーコントローラーの「Show Mouse Cursor」をONにすることで再び表示させることができます。

イベントBeginPlayを呼び出し、続いて図の通りノードを組むことでゲーム中にマウスカーソルを表示させることができる

続いてイベントグラフを右クリックし、メニューから「マウスの左ボタン」を選択してノードを作り、左クリックした際の動作を「マウスの左ボタン」ノードの「Pressed」ピンに繋げていきます。

「マウスの左ボタン」ノードは「Left Mouse…」などで検索できる

「Pressed」からノードをつなぐことでマウス左ボタンを押した時の処理を作ることが可能だ

ブロックを配置するためには、マウスでクリックした場所の3D空間上での位置を知る必要がありますUniversal Cameraのブループリントノードとして「Get Impact Point Under Cursor」という3D上でカーソルがどこにあるのか教えてくれるノードがあるので、これを活用しましょう。また、ブロックは1つ100.0のサイズで敷き詰めるように整列してほしいので、「Vector Snapped to Grid」という位置を自動でスナップしてくれるノードを使用し、「In Grid Size」を100.0に設定します。

「Get Impact Point Under Cursor」はマウスカーソルの下に特定のものがあるかどうかと、その3D上の位置を教えてくれる

「Vector Snapped to Grid」は位置などの情報を「In Grid Size」の数値でグリッド状にスナップできるノード

しかし、この位置のまま生成するとブロックが半分埋まってしまうような見た目になるので、取得した位置情報にZ方向50.0のオフセットをプラスし、その位置に静的な3Dモデルを扱う基本アクタ「StaticMeshActor」を生成することにします。

「クラスからアクタをスポーンします」を選択してスポーンアクタNONEという名前のノードを呼び出す

「Class」のピンに「StaticMeshActor」を指定するとノードがこの名前に変化する

ここまでの作業で、下の画像のようなノードになっているはずです。画像を参考にしながらノードを組んでみてください。

生成した「StaticMeshActor」ですが、このままだと「Mobility」という項目が全く動かさないことが前提の「Static」という状態になっているためにエラーが出ます。これを回避するために「Set Mobility」のノードを使って「Movable」に変更する必要があります

また、StaticMeshActorには最初は3Dモデルが設定されておらず、「見た目」が全くない状態なので「Set Static Mesh」のノードを使用し、マップ上の青いブロックなどに適用されている「SM_ChamferCube」などを設定しておきましょう。

さて、これでプレイしてみましょう。上手く行けば左クリックでカーソル位置にブロックが生成されるサンプルゲームができているはずです。

ブロックの上をクリックすると、さらに重ねて並べられる

それぞれのブロックの区別が分かりやすいように、生成時にランダムで色を付けてみると良いかもしれません。先ほどの続きとして、以下の画像のようにノードを組むと、ランダムな色をブロックに付けることができます。

Universal Cameraに限らず、ポーンやアクタというものの機能を知り、上手く利用することで制作できるゲームの幅が広がります。ぜひ、自分なりの手法でユニークなゲームを作ってみましょう!

『Universal Camera』ダウンロードページ
wvigler

アンリアルエンジンにハマり、ぷちコンでゲーム作ってた男。映像編で2連覇したことも。
昔はよくアーケードゲームとかやってました。
一番やり込んだのは「ケツイ ~絆地獄たち~」「戦国BASARAX」あたり。ローグライトゲームとかも好きです。

関連記事

「ゲームマーケット2024秋」レポート【後編】ICチップ、お菓子を使った個性際立つ一般ブースのボードゲームやLARPなど
2024.12.03
「ゲームマーケット2024秋」レポート【前編】初の幕張メッセで年末の新作ボードゲームを先行プレイ
2024.12.03
サイバーエージェント、技術カンファレンス「CADC2024」の講演記事を公開。ゲーム開発における事例として、「Figma」やAIを使った取り組みを紹介
2024.12.02
C++の最新動向と展望をチェック。C++の日本語リファレンスサイト「cpprefjp」メンバーの講演を、ゲームエンジン開発者がレポート&補足してみた【CEDEC2024】
2024.11.27
『あんさんぶるスターズ!!Music』MVをさまざまな端末で違和感なく表示する手法、Happy Elements カカリアスタジオが解説記事を公開
2024.11.27
『SINoALICE ーシノアリスー』が『シノアリスだったナニカ』に移行するまで。アプリサーバーなしで7年間のプレイ記録を後続アプリへ引き継ぐ【CEDEC2024】
2024.11.20

注目記事ランキング

2024.11.27 - 2024.12.04
VIEW MORE

連載・特集ピックアップ

イベントカレンダー

VIEW MORE

今日の用語

ローパスフィルター(Low-Pass Filter)
ローパスフィルター
  1. 電気信号のうち、指定した周波数(カットオフ周波数)以下の信号を通し、それより上を大きく低減させるフィルター。
  2. ゲーム開発において、基本的にはサウンド用語として用いられる。例として、特定のセリフをローパスフィルターによってくぐもった音に加工することで、隣の部屋や遮蔽物の後ろで話しているかのような表現を行うことができる。
VIEW MORE

Xで最新情報をチェック!