ゲームエンジン Unreal Engine 5 の基本機能

【概要】ゲームエンジンUnreal Engine 5の主な機能として、レベル階層構造、カメラシステム、ライティング、シャドウシステムがある。レベル階層構造はツリー構造のデータ構造で、3D空間内のオブジェクトを階層的に管理し、親アクターの変形が子アクターやコンポーネントに継承される特性がある。カメラはビューポートを通した視点を表現し、位置・向き・視野角の設定により、3D空間からスクリーン座標への変換を制御する。ライティングはアンビエントライト・ディレクショナルライト・ポイントライトなどの光源を組み合わせて、リアルな光の表現を可能にする。シャドウマッピングは光源からの深度情報を利用して影を生成する技術である。これらの技術要素を組み合わせることで、高品質で臨場感のある3D表現を実現できる。

【目次】

  1. 用語
    1. 3次元空間の基本概念
    2. レベル構造
    3. 3Dモデルの構成要素
    4. カメラと視点
    5. 照明と影
    6. レンダリングと入力処理
  2. Unreal Engine 5による3次元ゲーム開発の基礎
    1. 座標系の基本操作
    2. レベル管理の基本
    3. カメラ制御の基本
    4. ライティングの基本
    5. 入力処理の基本
    6. ティック管理の基本
    7. シャドウマッピングの基本

1. 用語

1.1 3次元空間の基本概念

3次元座標系

3次元座標系は、XYZ軸による3次元直交座標系で、3D空間内の位置を表現する基本的な仕組みである。X軸は左右、Y軸は前後、Z軸は上下を表す。点(2,3,1)は右に2、前に3、上に1の位置を示す。座標系には左手座標系と右手座標系の2種類がある。左手座標系は、左手の親指をX軸、人差し指をY軸、中指をZ軸の正方向に向けたときの配置で定義される。Unreal Engineは左手座標系をデフォルトとして採用しており、変更は推奨されない。ワールド座標系は空間全体の基準となる座標系であり、ローカル座標系はオブジェクトごとの基準となる座標系である。これらはオブジェクトの配置と移動の基礎となる。

Vector

Vectorは3D空間内の位置や方向と大きさを持つベクトルを表現する。位置と方向を表現することで、Set Actor Location(Location Vector(0, 0, 0))のように位置設定などの3D空間での操作を行える。点の減算でベクトルを得られ、点にベクトルを加えて新しい点を得られる。Vector(1,0,0)はX方向への単位ベクトルを表す。

1.2 レベル構造

レベル階層構造

レベル階層構造は、3D空間内のオブジェクトの階層構造を管理するツリー構造のデータ構造である。レベル内のアクターとコンポーネントの集合として表現され、座標変換や属性の継承が可能である。親の移動が子に影響し、子の移動は親に影響しない特性を持つ。Spawn Actor from Class関数で親アクターを作成するなど、3D空間の管理と操作のための仕組みである。

アクター

アクターは、レベル内のオブジェクトの基本クラスである。階層構造の中でオブジェクトへの参照を表し、Attach Actor Toで階層構造を構築し、Get Attached Actorsでアクターの親子関係を取得する。3Dオブジェクトの配置や変形を制御するために有用である。ワールドアウトライナーではすべてのアクターが表示される。

1.3 3Dモデルの構成要素

メッシュ

メッシュは、3Dモデルを構成する頂点、辺、面の集合である。ポリゴンの集合によって形状を表現する。テクスチャやマテリアルなどの表面属性を持つ。3Dオブジェクトの見た目を決定する要素の一つであり、複雑な形状の表現を可能にする。

ジオメトリ

ジオメトリは、3D空間内の形状データを表現する基本要素である。点、線、面などで構成され、頂点座標、法線ベクトル、テクスチャ座標などの属性を持つ。スタティックメッシュエディタで形状定義が行われ、レンダリングパイプラインで処理される。

頂点

頂点は、3D空間内の点を表す要素であり、位置座標(x,y,z)を持つ。法線ベクトル、色、テクスチャ座標などの付加的な属性を持ち、頂点シェーダで頂点データを処理できる。

ポリゴン

ポリゴンは、3つ以上の頂点で構成される面であり、3Dモデルの表面を形成するための要素である。最も基本的なポリゴンは三角形である。3D形状の表現の基礎であり、テクスチャマッピングにおいても使用される。

法線ベクトル

法線ベクトルは、面や頂点の向きを示す長さが1の単位ベクトルである。光の反射計算に利用される。法線ベクトルの向きは、面の表裏を判定する基準となる。スムーズシェーディングやノーマルマッピングなどの表現にも使用され、3Dオブジェクトの光沢や陰影表現に役立つ。マテリアルエディタでNormalノードを使用して法線を設定する。

テクスチャ

テクスチャは、3Dモデルの表面に貼り付ける画像データである。色や凹凸などの詳細な表現を可能にし、アルベド、ラフネス、メタリック、ノーマルマップなど複数のテクスチャを組み合わせることでより豊かな表現が可能となる。リアルな表面表現を実現する技術である。

1.4 カメラと視点

カメラ

カメラは、3D空間内の視点を表現する。3D空間からスクリーン座標への変換を制御するために利用される。位置、向き、視野角などのパラメータを持ち、透視投影または平行投影の投影方式を指定できる。Set Actor Location(0, -10, 3)のようにSet Actor Locationで位置を設定し、Set Actor Rotationで視線方向を設定する。

視野角

視野角は、カメラが捉える視界の広さを角度で表現するパラメータである。値が大きいほど広い範囲が見えるが画面の歪みも大きくなる。Set Field of Viewノードで視野角を設定する。

回転表現

回転表現は、ヨー、ピッチ、ロールという3つの角度で物体の向きを表現する方法である。ヨーは水平面内での回転、ピッチは縦方向の回転、ロールは軸周りの回転を表す。Make Rotatorノードでヨー、ピッチ、ロールの値を設定し、Set Actor Rotationノードで向きを設定する。ピッチ角が±90度に達すると、ジンバルロックと呼ばれる問題が発生する。ジンバルロックは、回転の自由度が失われる現象である。この問題を回避するため、ピッチ角の範囲を±90度未満に制限する。

1.5 照明と影

ライティング

ライティングは、3D空間内の光源と照明効果を制御するシステムである。アンビエントライト、ディレクショナルライト、ポイントライト、スポットライトなどの異なる種類の光源を組み合わせ、Set Intensityで強度を適用するなど、リアルな光の表現が可能となる。3D表現の質を決定する要素である。

光源の種類

3D空間を照らす光源には複数の種類がある。アンビエントライトは空間全体を均一に照らす。ディレクショナルライトは太陽光のような平行光線を生成する。Point Lightは点から全方向に広がる光、Spot Lightは円錐状の光を表現する。

シャドウマッピング

シャドウマッピングは、光源から見たシーンの深度情報を記録し、3D空間内のオブジェクトに影を付与する技術である。処理は2段階で行われる。第1段階では、光源の位置にカメラを配置し、シーンを描画して各ピクセルの深度情報をシャドウマップとして記録する。第2段階では、通常のカメラ視点から描画する際に、各ピクセルが光源から見えるかどうかをシャドウマップと比較して判定する。具体的には、描画中のピクセルの光源からの距離を計算し、シャドウマップに記録された深度値と比較する。ピクセルの距離がシャドウマップの深度値より大きい場合、そのピクセルは他のオブジェクトによって遮られており、影の中にあると判定される。

深度バッファ

深度バッファは、各ピクセルの奥行き情報を保持するメモリ領域である。オブジェクトの前後関係を表現するために使用され、見えない部分を除去する隠面消去の基本的なアルゴリズムを実現する。プロジェクト設定でDepth Buffer Bit Depthを変更できる。シャドウマッピングなどの高度な表現技術の基礎となる。

1.6 レンダリングと入力処理

レンダリング

レンダリングは、3D空間のデータを2D画像として描画する一連の処理過程である。モデリングデータの変換、光源計算、テクスチャマッピング、ピクセル処理など、複数の段階を経て最終的な画像を生成する。

キーボード/マウス入力

キーボード/マウス入力は、ユーザーからの操作を検出し処理する。キーの押下、保持、解放を区別し、マウスは位置と移動量を検出する。Input Action Mappingでスペースキーにジャンプアクションを割り当てるなど、イベントシステムを通じて入力イベントを処理する。Unreal Engineのイベントシステムは、入力を検出すると即座に対応するイベントハンドラを呼び出す仕組みであり、イベント発生時に実行されるノードシーケンスで対応する処理を実行する。ユーザーとのインタラクションを実現する基盤である。

ティック管理

ティック管理は、定期実行や遅延実行の管理を行う。Event Tickノードで定期実行処理を登録し、Delta Secondsピンでフレーム間の経過時間を取得する。入力処理、状態更新、描画の繰り返しであるゲームループの実装や時間に基づく処理の制御など、動的な3D環境の実現に必要な機能である。

2. Unreal Engine 5による3次元ゲーム開発の基礎

2.1 座標系の基本操作

3次元空間での位置指定

3次元空間での位置指定は、XYZ軸による3次元直交座標系で位置を表現する。X軸は左右、Y軸は前後、Z軸は上下を表す。点(2,3,1)は右に2、前に3、上に1の位置を示す。ワールド座標系とローカル座標系の2種類がある。

左手座標系

左手座標系は、親指(X)、人差し指(Y)、中指(Z)を直角に交差させた時の左手の形で表現される座標系である。Unreal Engineでは左手座標系をデフォルトとして採用している。回転方向や法線の判定では、座標系の定義に基づいて処理を行う。

ベクトルと点の違い

点は位置(2,3,1)を表し、ベクトルは方向と大きさを表す。点の減算でベクトルを得られ、点にベクトルを加えて新しい点を得られる。ベクトルの加減算や内積・外積の演算が3D空間の計算で重要である。

オブジェクトの配置と移動

オブジェクトの配置と移動を実装する手順を以下に示す。

  1. Make Vectorノードを配置し、X=0, Y=0, Z=0に設定
  2. Make Vectorノードの出力をSet Actor Locationノードの「New Location」ピンに接続
  3. Make Rotatorノードを配置し、Yaw=0, Pitch=0, Roll=0に設定
  4. Make Rotatorノードの出力をSet Actor Rotationノードの「New Rotation」ピンに接続
  5. Set Actor Scale 3Dノードを配置し、New Scale 3D入力に(1.0, 1.0, 1.0)を設定

レベルにキューブアクターを配置し、上記のブループリントをキューブアクターのEvent Beginplayイベントに接続する。実行するとキューブが原点(0,0,0)に配置され、回転なし、スケール1.0となることを確認できる。

相対移動

相対移動を実装する手順を以下に示す。

  1. Get Actor Locationノードを配置
  2. Make Vectorノードを配置し、X=1, Y=0, Z=0に設定
  3. 両ノードの出力をVector+Vectorノードに接続
  4. その結果をSet Actor Locationノードの「New Location」ピンに接続
  5. Set Actor Locationノードの「Sweep」をFalseに設定

キューブアクターに適用し実行すると、キューブがX軸方向に1単位移動することを確認できる。

2.2 レベル管理の基本

木構造によるデータ構造

木構造によるデータ構造は、親ノードと子ノードの階層関係を表現する構造である。3D空間では親の移動が子に影響し、子の移動は親に影響しない特徴を持つ。アニメーションやオブジェクトのグループ化に利用する。キャラクターの骨格構造も木構造で表現する。

階層構造の概念

階層構造の概念は、オブジェクト間の親子関係を管理する仕組みである。例えば、車体とタイヤ、腕と手の関係がある。

3Dモデルのファイル形式

3Dモデルのファイル形式として、FBX、OBJなどの形式で3Dモデルデータを保存する。形状、材質、テクスチャ、アニメーションなどの情報を含む。

ノードの階層構造

ノードの階層構造を構築する手順を以下に示す。

  1. Spawn Actor from ClassノードをEvent Beginplayの後に配置し、Class欄でCubeアクターを選択
  2. Spawn Actor from Classノードの「Return Value」出力ピンを変数「parent」に保存
  3. 別のSpawn Actor from ClassノードをSequence経由で配置し、Class欄でCubeアクターを選択
  4. 2つ目のSpawn Actor from Classノードの「Return Value」出力ピンを変数「child」に保存
  5. Attach Actor Toノードを配置し、「Target」に「child」、「Parent」に「parent」を接続
  6. Make Vectorノードを配置し、X=1, Y=0, Z=0に設定
  7. 「child」変数を取得し、Set Relative Locationノードに接続し、「New Location」にMake Vectorノードの出力を接続

実行後に親キューブを移動させると、子キューブも一緒に移動することを確認する。

モデルの読み込みと配置

モデルの読み込みと配置を実装する手順を以下に示す。

  1. Add Componentノードを配置してStatic Mesh Componentを追加
  2. コンテンツブラウザからStaticMeshアセットをノードの「Static Mesh」入力ピンにドラッグ&ドロップ
  3. Attach to Componentノードを使って、親コンポーネントにアタッチ
  4. Set Relative Locationノードでコンポーネントの位置を設定

実行後にメッシュが指定位置に表示されることを確認する。

2.3 カメラ制御の基本

視点と注視点の概念

視点と注視点の概念では、視点は観察者の位置、注視点は見つめる対象の位置を表す。この2点で視線方向が決定する。カメラワークの基本である。

視野角とクリッピング面

視野角は、カメラが捉える視界の広さを角度で表現するパラメータである。クリッピング面は表示距離の範囲を定義し、近接面と遠方面で設定する。

カメラの初期設定

カメラの初期設定を行う手順を以下に示す。

  1. Camera Actorをレベルに配置または「Spawn Actor from Class」ノードでスポーン
  2. Make Vectorノードを配置し、X=0, Y=-10, Z=3に設定してカメラ位置とする
  3. Make Vectorノードの出力をSet Actor Locationの「New Location」ピンに接続
  4. Make Vectorノードを別に配置し、X=0, Y=0, Z=0に設定して注視点とする
  5. カメラのGet Actor Locationノードとステップ4のMake Vectorノードの出力をFind Look at Rotationノードに接続
  6. Find Look at Rotationノードの出力をSet Actor Rotationノードに接続
  7. Set Field of Viewノードを配置し、視野角の値を設定

ゲームを実行し、カメラアクターがシーンの(0,0,0)位置を見下ろすように配置され、設定した視野角で表示されていることを確認する。

マウスによる視点回転

マウスによる視点回転を実装する手順を以下に示す。

  1. Event Tickノードを配置
  2. Get Mouse Deltaノードを配置してX,Y移動量を取得
  3. Get Actor Rotationノードを配置してカメラの現在の回転を取得
  4. Break Rotatorノードを配置してYaw、Pitch、Rollを分解
  5. Get Mouse DeltaのXピンに感度係数を乗算し、現在のYaw値に加算
  6. Get Mouse DeltaのYピンに感度係数を乗算し、現在のPitch値に加算
  7. Clampノードを使ってPitch値を±90度未満の範囲に制限
  8. Make Rotatorノードで新しいYaw、Pitch、Roll値を組み立て、Set Actor Rotationノードに接続

ピッチ角を±90度未満に制限する理由は、ジンバルロックを回避するためである。ゲーム実行中にマウスを動かすと、水平方向の動きでカメラが水平回転し、垂直方向の動きで設定した範囲内でのみカメラが垂直回転することを確認する。

2.4 ライティングの基本

光の基本特性

光の基本特性として、光の直進、反射、屈折、減衰の物理特性を考慮する。光源からの距離による減衰や物体表面での反射特性を再現する。色はRGB値で表現し、各成分は0から1の範囲である。

拡散反射と鏡面反射

拡散反射は光を全方向に均等に反射する。鏡面反射は特定方向への強い反射である。物理ベースレンダリングでは、これらの反射特性を物理法則に基づいて正確に再現する。マテリアルのプロパティでこれらを制御し、金属度パラメータは物体が金属かどうかを、粗さパラメータは表面の滑らかさを0から1の値で表現する。

光源の種類

3D空間を照らす光源には複数の種類がある。アンビエントライトは空間全体を均一に照らす。ディレクショナルライトは太陽光のような平行光線を生成する。Point Lightは点から全方向に広がる光、Spot Lightは円錐状の光を表現する。

光源の設定

光源を設定する手順を以下に示す。

  1. Ambient Lightアクターをレベルに配置
  2. 「Light」カテゴリの「Intensity」プロパティを0.2に設定
  3. 「Light」カテゴリの「Light Color」プロパティをRGBで(0.2, 0.2, 0.2)に設定
  4. Directional Lightアクターをレベルに配置
  5. 「Light」カテゴリの「Intensity」プロパティを1.0に設定
  6. 「Light」カテゴリの「Light Color」プロパティをRGBで(1, 1, 1)に設定

ブループリントでこれらのライトを操作する場合の手順を以下に示す。

  1. Spawn Actor from Classノードを配置し、Class欄でAmbient Lightアクターを選択
  2. Spawn Actor from Classノードの「Return Value」出力ピンから「Set Intensity」ノードに接続し、値を0.2に設定
  3. 同様に「Set Light Color」ノードに接続し、RGBで(0.2, 0.2, 0.2)に設定
  4. 別のSpawn Actor from Classノードを配置し、Class欄でDirectional Lightアクターを選択
  5. Spawn Actor from Classノードの「Return Value」出力ピンから「Set Intensity」ノードに接続し、値を1.0に設定
  6. 同様に「Set Light Color」ノードに接続し、RGBで(1, 1, 1)に設定

シーンにいくつかのオブジェクトを配置し、Ambient Lightの強度を変更すると全体的な明るさが変化し、Directional Lightの回転を変えると影の方向が変わることを確認する。

2.5 入力処理の基本

イベント駆動プログラミング

イベント駆動プログラミングでは、キー入力やマウス操作をイベントとして検出する。コールバック関数で対応する処理を実行する。Unreal Engineのイベントシステムは、入力を検出すると即座に対応するイベントハンドラを呼び出す仕組みである。

キーボード/マウス入力の仕組み

キーボード/マウス入力の仕組みでは、キーの押下、保持、解放を区別する。マウスは位置と移動量を検出する。移動での相対モードではカーソルを中心に固定し移動量のみ使用する。

入力状態管理

入力状態管理では、現在の入力状態をフラグや数値で保持する。キーの同時押しにも対応できる。入力履歴の管理で連続技なども実現できる。

キー入力の設定

キー入力を設定する手順を以下に示す。

  1. プロジェクト設定の「Input」セクションで新しい「Action Mapping」を追加
  2. 「Jump」という名前のアクションに「Space」キーをマッピング
  3. 「Quit」という名前のアクションに「Escape」キーをマッピング
  4. ブループリントで「InputAction Jump」イベントノードを配置
  5. 「InputAction Quit」イベントノードを配置し、Quit関数に接続

ゲーム実行中にスペースキーを押すとジャンプイベントが発火し、Escapeキーを押すとゲームが終了することを確認する。

キー状態の管理

キー状態を管理する手順を以下に示す。

  1. ブループリント内で「W Pressed」と「A Pressed」というブール変数を作成
  2. Event Beginplayノードから各変数をFalseに初期化
  3. 「InputAction W」イベントノードを配置し、「Pressed」イベントから「W Pressed」変数をTrueに設定
  4. 「InputAction W」イベントノードの「Released」イベントから「W Pressed」変数をFalseに設定
  5. 「A」キーについても同様に設定

ゲーム実行中にW、Aキーの状態に応じてPrintStringノードでデバッグメッセージを表示させ、キーを押すとTrue、離すとFalseになることを確認する。

2.6 ティック管理の基本

ゲームループ

ゲームループでは、入力処理、状態更新、描画を繰り返す。フレームレートの制御、時間管理が重要である。固定時間ステップと可変時間ステップの使い分けが必要である。

フレームレートと時間管理

フレームレートは1秒あたりの画面更新回数である。60FPSの場合、1フレームあたりの時間は$$\frac{1}{60}$$秒となる。処理負荷による変動を考慮し、前フレームからの経過時間であるDelta Secondsに基づいて動きを調整することが重要である。垂直同期でティアリングを防止する。

タスクスケジューリング

タスクスケジューリングでは、定期実行や遅延実行の管理を行う。優先度による実行順序の制御を行う。

定期実行タスクの登録

定期実行タスクを登録する手順を以下に示す。

  1. Event Tickノードを配置
  2. Event TickノードのDelta Secondsピンを変数に保存または直接使用
  3. UpdateGameという新しい関数を作成
  4. Event TickノードのExecuteピンをUpdateGame関数に接続
  5. UpdateGame関数内でDelta Seconds値を使ってキャラクター移動量などを計算

PrintStringノードを使ってDelta Secondsの値を表示する。60FPSのゲームの場合、Delta Secondsは$$\frac{1}{60}$$秒となる。オブジェクトを一定速度で移動させる場合、$$\text{移動距離} = \text{速度} \times \text{Delta Seconds}$$の関係式を用いる。

2.7 シャドウマッピングの基本

シャドウマッピングの原理

シャドウマッピングは、光源から見たシーンの深度情報をもとに、3D空間内のオブジェクトに影を付与する技術である。処理は2段階で行われる。第1段階では、光源の位置にカメラを配置し、シーンを描画して各ピクセルの深度情報をシャドウマップとして記録する。第2段階では、通常のカメラ視点から描画する際に、各ピクセルが光源から見えるかどうかをシャドウマップと比較して判定する。具体的には、描画中のピクセルの光源からの距離を計算し、シャドウマップに記録された深度値と比較する。ピクセルの距離がシャドウマップの深度値より大きい場合、そのピクセルは他のオブジェクトによって遮られており、影の中にあると判定される。

アーティファクトと対策

シャドウマッピングでは、シャドウアクネ、エイリアシングなどの問題が発生する。シャドウアクネは、深度バッファの精度不足により、本来影にならない部分に斑点状の影が現れる現象である。バイアス値を調整することで、この問題を軽減できる。エイリアシングは、シャドウマップの解像度不足により、影の境界にジャギーが現れる現象である。PCFやカスケードシャドウなどの手法で対策する。

シャドウマップの設定

シャドウマップを設定する手順を以下に示す。

  1. Directional Lightアクターをレベルに配置
  2. 「Light」カテゴリの「Cast Shadows」をTrueに設定
  3. 「Light」カテゴリの「Shadow Resolution Scale」を1.0に設定
  4. 「Light」カテゴリの「Dynamic Shadow Distance MovableLight」を設定
  5. 「Cascaded Shadow Maps」セクションで「Num Dynamic Shadow Cascades」を設定

ブループリントでシャドウ設定を変更する場合は、Directional Lightアクターへの参照を取得し、「Set Cast Shadows」ノードをTrueに設定し、「Set Shadow Resolution Scale」ノードを1.0に設定する。光源の位置や角度を変更したときに影の位置や形が正しく変わることを確認する。また、「Shadow Resolution Scale」の値を下げると影の解像度が荒くなることも確認できる。