Unity から Unreal Engine への乗り換えガイド

Unity 経験者向けに Unreal Engine 5 について説明します。

Unity 使用経験があるユーザー向けに Unreal Engine (UE) の概要を説明します。以下の説明は、Unity の知識があり、これまで学んだことを Unreal Engine での作業に生かしたい方に役立ちます。

Unreal Editor

Unreal Editor は Unreal Engine プロジェクトの作業場所です。以下に Unity と Unreal Editor のスクリーンショットを並べています。各エリアを色分けして共通の機能を示しています。各ブロックは Unreal Engine で使われる用語を表示しています。

Unreal Editor のレイアウトは自由にカスタマイズできます。タブをドラッグアンドドロップしてメイン ウィンドウに結合したり、カラー スキームを変更したりできます。

unity-to-unreal-engine-ui-comparison.png

Unity と Unreal Engine 5 の主な UI 要素の視覚的比較。画像をクリックするとフルサイズで表示されます。

アセットを編集する

Unity では [Inspector (インスペクター)] タブを使ってプロジェクトのアセットを編集します。Unreal Editor では [Details (詳細)] パネルに選択したオブジェクトのプロパティが表示されます。複雑なアセットの編集は別のエディタ ウィンドウで行います。このウィンドウはメインUEウィンドウに結合したり、デスクトップの別の場所 (2 台目のモニターなど) にドラッグしたりできます。

unreal-engine-tabbed-editors.png

タブ化した Unreal Editor のエディタ。レベル エディタ が背面にあり、マテリアル エディタ が現在アクティブになっています。

Unreal Engine の各種アセット エディタの説明については、「ツールとエディタ」を参照してください。

クイック用語集

以下のセクションでは、左に Unity 用語、右に対応する (または類似する) Unreal Engine 用語を表示しています。Unreal Engine 列の各用語は、各詳細ページにリンクしています。

カテゴリ

Unity

Unreal Engine

ゲームプレイ タイプ

コンポーネント

コンポーネント

ゲームオブジェクト

アクタ

プレハブ

ブループリント クラス

エディタ UI

ヒエラルキー パネル

ワールド アウトライナ

インスペクター

詳細パネル

プロジェクト ブラウザ

コンテンツ ブラウザ

シーン ビュー

レベル ビューポート

メッシュ

メッシュ

スタティック メッシュ

スキン メッシュ

スケルタル メッシュ

マテリアル

シェーダー

マテリアルマテリアル エディタ

マテリアル

マテリアル インスタンス

エフェクト

パーティクルエフェクト

エフェクト、パーティクル、Niagara

ゲーム UI

UI

UMG (Unreal Motion Graphics)

アニメーション

アニメーション

スケルタル メッシュ アニメーション システム

Mecanim

アニメーション ブループリント

シーケンス

シーケンサー

2D

スプライト エディタ

Paper2D

プログラミング

C#

C++

スクリプト、Bolt

ブループリント

物理

レイキャスト

ライン トレース、シェイプ トレース

リジッドボディ

コリジョン、物理

ランタイム プラットフォーム

iOS プレイヤー、Web プレイヤー

プラットフォーム

プロジェクトとファイル

Unreal Engine プロジェクトでよく使うファイルとディレクトリ

Unreal プロジェクトは Unity プロジェクトと同様に、常に独自のディレクトリに存在し、.uprojectfile という拡張子の独自のプロジェクト ファイルを持ちます。.uproject ファイルを ダブルクリック してゲームを Unreal Editor にロードしたり、右クリック してオプションを表示させたりできます。

プロジェクト フォルダ内には、ゲームのコンテンツやソースを含む各種のサブフォルダのほか、各種のコンフィギュレーション ファイルやバイナリがあります。特に重要なのが、プロジェクトのすべてのアセットを格納している Content フォルダと、プロジェクトのコンフィギュレーション (.ini) ファイルを格納している Config フォルダです。

アセットの保存場所

Unreal Engine では、各プロジェクトに 1 つ Content フォルダがあります。Unity プロジェクトの Assets フォルダと同様に、ここにゲームのアセットが格納されます。

Unreal Engine プロジェクトに C++ クラスが含まれる場合は、ディスク上のプロジェクトの Source フォルダに格納されます。

アセットをゲームにインポートするには、コンテンツ ブラウザ を通じてプロジェクトの Content ディレクトリにファイルをドロップします。

アセットのインポート プロセスの詳細については、「アセットを直接インポートする」を参照してください。

対応ファイル フォーマット

Unreal Engine 5 がサポートしている代表的なファイル タイプは次のとおりです。

アセット タイプ

対応フォーマット

3D

.fbx、.obj

テクスチャ

.png、.jpeg、.bmp、.tga、.dds、.exr、.psd、.hdr

サウンド

.wav

フォント

.ttf、.otf

映像

.mov、.mp4、.wmv

また、専用プラグインを使って以下のようなタイプのコンテンツをインポートできます。

プラグイン

対応コンテンツ

Datasmith

3ds Max、SketchUp、Revitなど、各種 CAD アプリケーションからの 3D シーンやアセット

LiDAR Point Cloud プラグイン

LiDAR 点群。対応ファイル タイプの一覧については、「LiDAR Point Cloud プラグインの概要」を参照してください。

USD Importer

.usd (ユニバーサル シーン デスクリプション)

Alembic ファイル インポーター

.abc

シーンを格納するには

Unity ではシーンにゲームオブジェクトを配置し、シーン アセット ファイルとして保存します。Unreal Engine には、Unity のシーンに似た マップ ファイル があります。マップ ファイルは、レベル とその中のオブジェクトに関するデータに加え、ライティング データとレベル特有の一部の設定を格納しています。

プロジェクト設定を変更するには

Unreal Editor のメイン メニューから [Edit (編集)] > [Project Settings (プロジェクト設定)] を選択します。

Unity のプロジェクト設定と同様に、次のような設定があります。

  • プロジェクト名やアイコンなど、プロジェクトに関する情報の管理。

  • ゲームの入力バインディングの設定。

  • プロジェクト実行時のエンジン動作の定義。

  • その他。

プロジェクト設定 の詳細については、「プロジェクト設定」を参照してください。

Unity にも「プレイヤー設定」と呼ばれるものがあります。Unreal Engine では、これは プラットフォーム設定 であり、Project Settings ウィンドウの Platforms セクションで設定できます。

ソース ファイルの格納場所

Unity では Assets フォルダに C# ソース ファイルを格納します。Unreal Engine では、作成する Unreal プロジェクトのタイプに応じて異なる場所にソース ファイルを格納します。

  • C++ プロジェクト の場合、Unreal プロジェクト ディレクトリに Source フォルダがあります。Source フォルダには、C++ ソース ファイル (.cpp) やヘッダ ファイル (.h) などの各種ファイルと、一部のビルド スクリプト (Build.csTarget.cs) が含まれます。

  • ブループリント プロジェクト には Source フォルダがありません。ブループリントは、Unreal プロジェクトの Content フォルダのどこかに格納されます。

ブループリント プロジェクトに C++ コードを追加する場合、Unreal Editorのメイン メニューから [Tools (ツール)] > [New C++ Class (新規 C++ クラス)] を選択します。

コンテンツ ブラウザ で C++ ソース ファイルをダブルクリックすると、Visual Studio (Windows) または Xcode (macOS) で開きます。

ゲームオブジェクトからアクタに切り替える

ゲームオブジェクトはどうなるのか

Unity では、ゲームオブジェクトはワールドに配置できる「物」にあたります。Unreal Engine で同等のものは アクタ です。Unreal Editor では、下に示すように、メイン ツールバー[Create (作成)] メニューでビューポートに新規の空のアクタをドラッグします。

空のアクタからでもゲームをビルドできますが、Unreal Engine には ポーン (プレイヤーや AI がコントロールできるアクタ) や キャラクター (複雑なロコモーションやインタラクションを必要とするコントロール可能なプレイヤー キャラクター) など特殊なタイプのアクタもあります。特殊なタイプのアクタも空のアクタと同様にビューポートにドロップし、プロパティやコンポーネントを追加したりカスタマイズしたりできます。

Unreal Engine には、特殊なアクタに使える ゲームプレイ フレームワーク があります。ゲームプレイ フレームワークについては後ほど説明します。

Unreal Engine のアクタは Unity のゲームオブジェクトと少し違う点があります。Unity のゲームオブジェクトは、直接拡張できない C# クラスです。Unreal Engine のアクタは、継承を使って拡張したりカスタマイズしたりできる C++ クラスです。継承については後ほど説明します。

コンポーネントはどうなるのか

Unity ではコンポーネントを使ってゲームオブジェクトに機能を追加していました。Unreal Engine ではアクタにコンポーネントを追加します。空のアクタをレベルにドロップしたら、それを選択して [Details] パネルの [Add Component (コンポーネントを追加)] ボタンをクリックし、追加するコンポーネントを選択します。

下の動画では、トーチを作成するために空のアクタをドロップして、ベースにメッシュ コンポーネントを追加し、光源とパーティクル システムを追加して炎を作っています。

Unity ではゲームオブジェクトのコンポーネント リストに階層はありません。Unreal Engine のアクタには、コンポーネントが互いにアタッチしてできた 階層 が含まれます。上の例で言えば、ライトとパーティクルがスタティック メッシュにアタッチされています。これには重要な意味があり、このページの 複合オブジェクト のセクションで説明しています。

Unity のプレハブから Unreal Engine のブループリント クラスに移行する

Unity ではコンポーネントでゲームオブジェクト セットをビルドし、そこからプレハブを作成します。そしてプレハブのインスタンスをワールドに配置したり、実行時にインスタンス化したりします。

Unreal Engine では、ブループリント クラスをベースにした同様のワークフローがあります。

  1. コンポーネントを持つアクタをビルドします。

  2. アクタの [Details] パネルで [Blueprint (ブループリント)] > [Add Script (スクリプトの追加)] をクリックし、ブループリントを追加します。

  3. 新しいブループリント クラスの保存先を選択します。

  4. [Create Blueprint (ブループリントの作成)] をクリックします。

以上です。

コンテンツ ブラウザ から新しいブループリント クラスにアクセスできます。ダブルクリック して直接編集したり、開いたレベルにドラッグしてゲーム ワールドに配置したりできます。

スクリプト コンポーネントと MonoBehaviour はどうなるのか

Unity には、ゲームオブジェクトにドロップして C# スクリプトを追加できるスクリプト コンポーネントがあります。そのコンポーネントの動作は、MonoBehaviour から継承するクラスを作成して定義します。

Unreal Engine でも同様で、ブループリントや C++ を使用して完全に新規のコンポーネント クラスを作成し、それをアクタに追加できます。アクタにブループリントを追加するのと同様に、次の 2 つの方法のいずれかでアクタにコンポーネントを追加できます。

  • アクタの [Details] パネル。

  • [Edit Actor (アクタの編集)] ウィンドウ。

アクタに新しいコンポーネントを追加する手順は次のとおりです。

  1. アクタの [Details] パネルまたは [Edit Actor] ウィンドウから [Add Component] をクリックします。

  2. アクタに追加するコンポーネントを選択します。新規のコンポーネントを作成するか、ライト、オーディオ、パーティクル システムなどの事前定義コンポーネントのリストから選択できます。

    Adding a Component to an Actor

Unity で新規の MonoBehaviour を作成すると、Start() 関数と Update() 関数を持つスケルトン クラス ファイルを受け取ります。

Unreal Engine では新規のコンポーネントに同様の関数が含まれます。

  • InitializeComponent() (Unityの Start()` 関数と同じ役割)

  • TickComponent() (Unity の Update() 関数と同じ役割)

ブループリント コンポーネントでは、これらの関数がビジュアル ノードとして表示されます。

スクリプト可能なアクタ ブループリント クラス

新規のアクタ ブループリント クラスには、独自のブループリント ビジュアル スクリプトが含まれます。それにより、個々のコンポーネントだけでなくオブジェクト全体にロジックを追加できます。継承 (説明は後述) と組み合わせると、ゲーム デザインの柔軟性が高まります。

Unreal Engine はブループリント クラスでビジュアル スクリプトに対応するほか、C++ クラスをコードで実装することもできます。以下に Unity と Unreal Engine のコードを並べて示し、同じ内容を実行する Unreal Engine のブループリントも示します。

Unity C#

    using UnityEngine;
    using System.Collections;

    public class MyComponent : MonoBehaviour
    {
        int Count;

        // 初期化にこれを使用します。
        void Start ()
        {
            Count = 0;
        }

        // フレームごとに1度更新が呼び出されます
        void Update ()
        {

            Count = Count + 1;
            Debug.Log(Count);
        }
    }

Unreal Engine C++

    #pragma once
    #include "GameFramework/Actor.h"
    #include "MyActor.generated.h"

    UCLASS()
    class AMyActor : public AActor
    {
        GENERATED_BODY()
        int Count;

        // このアクタのプロパティにデフォルト値を設定します。
        AMyActor()
        {
            // Tick()の呼び出しを許可します。
            PrimaryActorTick.bCanEverTick = true;
        }

        // ゲーム開始時またはスポーン時に呼び出されます。
        void BeginPlay()
        {
            Super::BeginPlay();
            Count = 0;
        }

        // フレームごとに呼び出されます。
        void Tick(float DeltaSeconds)
        {
            Super::Tick(DeltaSeconds);
            Count = Count + 1;
            GLog->Log(FString::FromInt(Count));
        }
    };

ブループリント

(image_28.png)

ブループリント クラスは拡張可能

Unity のプレハブと同様に、Unreal Engine のブループリントもインスタンス化できます。

Unreal Engine では、既存のブループリント クラスを拡張して新しいプロパティ、コンポーネント、ビジュアル スクリプト機能で増強し、新しいブループリント クラスを作成できます。

たとえばモンスターという名前のブループリントクラスを作成し、人々を追いかけるというような基本的なモンスターの機能を実装します。次にそれを拡張して、ドラゴン (火を噴く能力を追加したモンスター)、グルー (夜だけやって来るモンスター)、その他 8 つのさまざまなモンスターのブループリント クラスを作成します。モンスターのこうしたサブクラスはすべて、モンスターの基本機能を継承すると同時に、各自の新たな特徴と能力も持っています。

Unity でこれを実装するには、たくさんの異なるゲームオブジェクト プレハブを作成する必要があります(ドラゴン用に 1 つ、グルー用に 1 つなど)。次に、新たに発話コンポーネントを使って話せるようにするなど、すべてのモンスターに新機能を追加するとします。Unity では、新機能を個々にコピー ペーストして 10 個のプレハブ全部を更新する必要があります。

Unreal Engine では、モンスターのブループリント クラスに新たに発話能力を追加して修正するだけで済みます。作業はそれだけです。ドラゴン、グルー、その他 8 つのモンスターのサブクラスは、新規の発話機能を自動的に継承するので、特に手を加える必要はありません。

このセクションの内容は、C++ クラスのほか、アクタとコンポーネントにも当てはまります。こうしたシステムは、拡張機能を大規模に開発できるよう設計されています。数十人または数百人のデベロッパーが関わるプロジェクトに拡大できます。

ブループリント スクリプト、C++、またはその両方を使用する

ブループリント ビジュアル スクリプトは、インゲームのロジックやアクションのシンプルなシーケンシングに最適です。ブループリントはインゲームのオブジェクトに視覚的にアクセスし管理できるので、デザイナ、アーティスト、ビジュアル志向のプログラマーにとっては非常に便利なシステムです。ブループリントだけを使って、スタンドアローンのミニ ゲームやインタラクティブなエクスペリエンスを作成できます。

C++ プログラミングは、ゲームプレイ システム、複雑な AI、新しいエンジン機能のビルドなど、大規模なタスクに適しています。C++ の経験がある場合、「C++ を使用したプログラミング」を参照して、Unreal Engine の C++ プログラミングについて詳細をご覧ください。

ほとんどのプロジェクトではブループリントと C++ を併用します。デベロッパーの多くは、試作と改善の繰り返しが簡単なブループリントを使ってゲーム機能を試作し、その後一部または全部を C++ に移して性能や設計の詳細を詰めます。

ブループリント クラスは C++ クラスを拡張可能

Unreal Engine のゲーム開発の素晴らしい点は、プログラマーが C++ で新機能を実装し、デザイナやアーティストがそれをブループリントでテストして実際的なフィードバックをするという相互作用にあります。以下は、UE ベースのシューティングゲームのピックアップの実装を、プログラミングに C++ クラス システムを使い、動作と外観にブループリント クラスを使って、チームがどのように構成しているかを表しています。

Class inheritance in Unreal Engine

トランスフォーム コンポーネント

Unity では各ゲームオブジェクトにトランスフォーム コンポーネントが含まれ、ワールド内での位置、回転、スケールをゲームオブジェクトに与えています。

同様に Unreal Engine のアクタにも、シーン コンポーネントのサブクラスとなるような ルート コンポーネント があります。シーン コンポーネント はワールド内での位置、回転、スケールをアクタに与えますが、これはそのシーン コンポーネントを親とするすべてのコンポーネントに適用されます。位置を含むのが便利であるため、使用するコンポーネントの多くはシーン コンポーネントのサブクラスになります。

空のアクタを配置する場合でも、Unreal Engine はそのアクタにデフォルトのシーン ルートを作成します。これはプレーンなシーン コンポーネントです。新たにシーン コンポーネントをドロップすると、それがデフォルトのシーン ルートに置き換わります。

複合オブジェクト

Unity ではゲームオブジェクトの階層を構築し、トランスフォームを親子関係にすることで、複合オブジェクトを作成します。

Unity GameObject relations

Unreal Engine では、コンポーネントを階層的にネストすることで複合ゲームオブジェクトを作成します。

Unreal Engine Actor and Component relations

図からわかるように、シーン コンポーネントを互いにアタッチすることで階層をネストできます。Unity でトランスフォームを親子関係にする場合と同様に、トランスフォームが含まれるからです。アクタ コンポーネント (すべてのコンポーネントの基本クラス) は、アクタ自体に直接アタッチします。

コンポーネントからすべてビルドするのか

ユーザーの選択次第です。通常は、カスタムのコンポーネント タイプの組み合わせと、そうしたコンポーネントを使うアクタ クラスを一緒に使用します。前述のように、Unreal Engine には特殊なアクタ タイプがたくさんあり、これらは一定のレベルの能力を確保していて、常にいくつかコンポーネントを含んでいます。たとえば、Character には常に Character Movement コンポーネント が含まれます。

よく使われる Unreal Engine のアクタを以下に挙げます。

  • ポーン - プレイヤーのアバターなど、コントロール可能なゲームオブジェクトを表すアクタ タイプです。ポーンは、プレイヤーや AI が各自のコントローラーを通じて動かします。

  • キャラクター - ポーンの特殊バージョンで、二足歩行のアバター (人間と似たスケルタル構造を持ち二足歩行するアバター) です。

  • コントローラー - ポーンを所有しコントロールします。コントローラーからポーンを分離することで、プレイヤーと同じインターフェースを使ってポーンを操作できる AI コントローラーを記述できます。

  • プレイヤー コントローラー - プレイヤーのゲームパッド、タッチ、マウス/キーボードからプレイヤーの入力を取得し、その入力に基づきプレイヤーのポーンやキャラクターを動かすよう設計された専用コントローラーです。

すべてのものがアクタなのか

すべてではありません。アクタ は Unreal Engine のゲームプレイで最もよく使われるクラスで、ワールドスポーン できる唯一のタイプです。つまり、レベルに配置するものはすべてアクタになります。

もう一つの重要なタイプに オブジェクト があります。オブジェクトは事実上、アクタ などすべての Unreal クラスの基本クラスです。アクタよりずっと下位レベルの構成概念ですが、リフレクションシリアル化 など、Unreal クラスに求められる機能を持っています。オブジェクトは、アクタ の型に適さない新たなタイプを定義する場合に使用する極めて基本的なクラスです。たとえば、アクタ コンポーネント はすべてのコンポーネントの基本クラスですが、アクタ ではなく オブジェクト から派生します。

Unreal Engine のゲームプレイ フレームワークとは

新規の Unity プロジェクトを開始する場合、ゲームオブジェクトやコンポーネントなどの物を手動で入力する必要があります。Unreal Engine でも同様に、アクタやコンポーネントを使ってゲームをビルドできます。ただし Unreal Engine には、ゲームプレイ フレームワーク と呼ばれるレイヤーがあります。特定のプリミティブ クラスを使用して決まりに従うと、本来なら実装が難しく時間のかかる追加機能 (マルチプレイヤーへの完全対応など) を、自動的にゲームに取り入れられます。

ゲームプレイ フレームワークを使うには、ポーンキャラクタープレイヤー コントローラー など、Unreal Engine 内蔵のアクタ クラスの使い方とカスタマイズの仕方を学ぶ必要があります。たとえばマルチプレイヤーを実装する場合、Unreal Engine のネットワークやレプリケーションの仕組みを理解する必要があります。

Unreal Engine でコードを記述する

C++ プログラマーの場合

ブループリント スクリプトは Unreal Engine だけがあれば使用できます。必要な機能はすべて組み込まれています。

C++ でコードを記述する場合、Windows には Visual Studio をダウンロードし、macOS には Xcode をインストール します。Unreal Engine で新規の C++ プロジェクトを初めて作成する場合 (または既存のプロジェクトに C++ コードを追加する場合)、Unreal Engine はユーザーに代わって自動的に Visual Studio プロジェクト ファイルを作成します。

Unreal Engine プロジェクトから Visual Studio にアクセスする方法は次の 2 つです。

  • コンテンツ ブラウザ で C++ クラスを ダブルクリック し、Visual Studio で開きます。

  • メイン メニューから [Tools] > [Open Visual Studio (Visual Studio を開く)] を選択します。このオプションは、プロジェクトに C++ クラスが 1 つ以上含まれる場合にのみ表示されます。

Unreal Engine で異なる重要な点が 1 つあります。Visual Studio プロジェクト ファイルはときどき手動でリフレッシュする必要があります (新バージョンの Unreal Engine をダウンロードした後や、ディスク上のソース ファイルの場所を手動で変更したときなど)。これには次の 2 つの方法があります。

  • Unreal Engine のメイン メニューから [Tools] > [Refresh Visual Studio Project (Visual Studio プロジェクトのリフレッシュ)] を選択します。

  • プロジェクトのディレクトリで「.uproject」ファイルを 右クリック し、[Generate Visual Studio project files (Visual Studio プロジェクト ファイルの生成)] を選択します。

イベント関数 (Start や Update など) を記述する

MonoBehaviors の使用経験があれば、StartUpdateOnDestroy などのメソッドには慣れているでしょう。以下に、Unity での動作と、Unreal Engine のアクタやコンポーネントでこれに相当する動作との比較を挙げます。

Unity ではこのようなシンプルなコンポーネントになるでしょう。

    public class MyComponent : MonoBehaviour
    {
        void Start() {}
        void OnDestroy() {}
        void Update() {}
    }

Unreal Engine では新規のコンポーネント タイプをコーディングするだけでなく、アクタ自体に対してコードを記述できます。このやり方が実際によく使われており、便利です。

Unreal Engine のアクタには、Unity の StartOnDestroyUpdate 関数に似たメソッドがあります。それらを以下に挙げます。

C++

    UCLASS()
    class AMyActor : public AActor
    {
        GENERATED_BODY()

        // ゲーム開始時に呼び出されます。
        void BeginPlay();

        // 破壊されたときに呼び出されます。
        void EndPlay(const EEndPlayReason::Type EndPlayReason);

        // このアクタを更新するために毎フレーム呼び出されます。
        void Tick(float DeltaSeconds);
    };

ブループリント

image_29.png

Unreal Engine のコンポーネントにはさまざまな関数が含まれます。以下に基本的な例を挙げます。

C++

    UCLASS()
    class UMyComponent : public UActorComponent
    {
        GENERATED_BODY()

        // 所有するアクタが作成された後に呼び出されます。
        void InitializeComponent();

        // コンポーネントまたは所有するアクターが破壊されるときに呼び出されます。
        void UninitializeComponent();

        // Tickのコンポーネント版
        void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction);
    };

ブループリント

image_30.png

Unreal Engine ではメソッドの親クラスのバージョンを呼び出す必要があります。

たとえば Unity の C# では base.Update() ですが、Unreal Engine の C++ では Super::TickComponent() を使います。

    void UMyComponent::TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
    {
        // カスタムチックはここです
        Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
    }

C++ ではプレフィックス A を使うクラスとプレフィックス U を使うクラスがあります。A はアクタのサブクラスを表し、Uオブジェクト のサブクラスを表します。ほかにも一般的なプレフィックスがあり、F はプレーンなデータ構造と UObject 以外のクラスの多くに使われています。

Unreal Engine でゲームプレイを作成する

次のセクションでは、Unreal Engine の先進的なプログラミング コンセプトについて説明します。以下の説明は、Unity の C# の経験がある上で Unreal Engine の C++ を学ぶことを前提にしています。多くの場合、ブループリントを使って同じ結果が得られるので、可能な限り C++ とブループリントの両方の例を挙げています。

よく使われるゲームプレイ プログラミング パターンと、Unreal Engine でそれをどのように実行するかについて説明します。以下に、Unity でよく使う関数と、Unreal Engine で同じ機能を実装する方法の例を挙げます。

ゲームオブジェクトをインスタンス化する / アクタをスポーンする

Unity では Instantiate 関数を使ってオブジェクトのインスタンスを新たに作成します。この関数は UnityEngine.Object 型 (ゲームオブジェクトやMonoBehaviourなど) を取り、コピーを作ります。

    public GameObject EnemyPrefab;
    public Vector3 SpawnPosition;
    public Quaternion SpawnRotation;

    void Start()
    {
        GameObject NewGO = (GameObject)Instantiate(EnemyPrefab, SpawnPosition, SpawnRotation);
        NewGO.name = "MyNewGameObject";
    }

Unreal Engine でオブジェクトをインスタンス化するには次の 2 つの関数があります。

  • NewObject は新しく UObject 型を作成します。

  • SpawnActorAActor 型をスポーンします。

UObjects と NewObject

Unreal Engine の UObject のサブクラス化と Unity の ScriptableObject のサブクラス化は非常に似ています。ワールドにスポーンする必要がないゲームプレイ クラスや、アクタのようにアタッチされたコンポーネントを持つゲームプレイ クラスに便利に利用できます。

Unity で ScriptableObject の独自のサブクラスを作成する場合、以下のようにインスタンス化します。

    MyScriptableObject NewSO = ScriptableObject.CreateInstance<MyScriptableObject>();

Unreal Engine で独自の UObject 派生型を作成する場合、以下のようにインスタンス化します

    UMyObject* NewObj = NewObject<UMyObject>();

AActors と SpawnActor

アクタは SpawnActor メソッドでワールド オブジェクト (C++ では UWorld) にスポーンされます。一部の UObjects はユーザーに GetWorld メソッドを提供します (たとえばすべてのアクタが提供します)。この方法でワールド オブジェクトを取得できます。

以下の例では、もう一つのアクタを渡す代わりに、スポーンしたいアクタのクラスを渡します。この例では、クラスは AMyEnemy の任意のサブクラスです。

Unity で Instantiate を使用すればできるように、別のオブジェクトのコピーを作る場合はどうすればよいでしょうか。

NewObject および SpawnActor 関数と使用できるテンプレート オブジェクトがあります。Unreal Engine は、新規オブジェクトをゼロから作成するのではなく、オブジェクトのコピーを作成します。UPROPERTY とコンポーネントがすべてコピーされます。

    AMyActor* CreateCloneOfMyActor(AMyActor* ExistingActor, FVector SpawnLocation, FRotator SpawnRotation)
    {
        UWorld* World = ExistingActor->GetWorld();
        FActorSpawnParameters SpawnParams;
        SpawnParams.Template = ExistingActor;
        World->SpawnActor<AMyActor>(ExistingActor->GetClass(), SpawnLocation, SpawnRotation, SpawnParams);
    }

この場合の「ゼロから」とはどういうことか疑問に思われるかもしれません。作成する各オブジェクト クラスには、プロパティとコンポーネントのデフォルト値を含むデフォルトのテンプレートがあります。それらのプロパティを書き換えたり独自のテンプレートを提供したりしなければ、Unreal Engine はデフォルト値を使ってオブジェクトを構築します。これを説明するため、MonoBehaviour の例を見てみます。

    public class MyComponent : MonoBehaviour
    {
        public int MyIntProp = 42;
        public SphereCollider MyCollisionComp = null;

        void Start()
        {
            // neコリジョンコンポーネントがまだない場合は作成します。
            if (MyCollisionComp == null)
            {
                MyCollisionComp = gameObject.AddComponent<SphereCollider>();
                MyCollisionComp.center = Vector3.zero;
                MyCollisionComp.radius = 20.0f;
            }
        }
    }

上記の例には、デフォルト値が 42 の int プロパティとデフォルト値が半径 20 の SphereCollider コンポーネントがあります。

Unreal ではオブジェクトのコンストラクタを使って同じものを実現できます。

    UCLASS()
    class AMyActor : public AActor
    {
        GENERATED_BODY()

        UPROPERTY()
        int32 MyIntProp;

        UPROPERTY()
        USphereComponent* MyCollisionComp;

        AMyActor()
        {
            MyIntProp = 42;

            MyCollisionComp = CreateDefaultSubobject<USphereComponent>(FName(TEXT("CollisionComponent"));
            MyCollisionComp->RelativeLocation = FVector::ZeroVector;
            MyCollisionComp->SphereRadius = 20.0f;
        }
    };

AMyActor のコンストラクタで、クラスにデフォルトのプロパティ値を設定しています。CreateDefaultSubobject 関数を使っていることに注意してください。この関数を使うと、コンポーネントを作成してデフォルト プロパティを割り当てることができます。この関数で作成したサブオブジェクト全体がデフォルト テンプレートとして機能し、サブクラスかブループリントで修正できます。

ある型から別の型にキャストする

この場合、あると分かっているコンポーネントを取得して、それを特定の型にキャストし、条件付きで何かを実行します。

Unity C#

    Collider collider = gameObject.GetComponent<Collider>;
    SphereCollider sphereCollider = collider as SphereCollider;
    if (sphereCollider != null)
    {
            // ...
    }

Unreal Engine C++

    UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());
    USphereComponent* SphereCollider = Cast<USphereComponent>(Primitive);
    if (SphereCollider != nullptr)
    {
            // ...
    }

ゲームオブジェクト / アクタを破壊する

Unity

    Destroy(MyGameObject);

C++

    MyActor->Destroy();

ブループリント

image_23.png

ゲームオブジェクト / アクタを破壊する (遅延 1 秒)

Unity

    Destroy(MyGameObject, 1);

C++

    MyActor->SetLifeSpan(1);

ブループリント

image_24.png ]

ゲームオブジェクト / アクタを無効化する

Unity

    MyGameObject.SetActive(false);

C++

    // 可視コンポーネントを非表示にします
    MyActor->SetActorHiddenInGame(true);

    // コリジョンコンポーネントを無効にします
    MyActor->SetActorEnableCollision(false);

    // アクタのカチカチ音を止めます
    MyActor->SetActorTickEnabled(false);

ブループリント

image_25.png ]

コンポーネントからゲームオブジェクト / アクタにアクセスする

Unity

    GameObject ParentGO =
    MyComponent.gameObject;

C++

     AActor* ParentActor =
     MyComponent->GetOwner();

ブループリント

image_32.png ]

ゲームオブジェクト / アクタからコンポーネントにアクセスする

Unity C#

    MyComponent MyComp = gameObject.GetComponent<MyComponent>();

Unreal Engine C++

    UMyComponent* MyComp = MyActor->FindComponentByClass<UMyComponent>();

ブループリント

image_33.png ] 画像をクリックするとフルサイズで表示されます。

ゲームオブジェクト / アクタを検索する

Unity C#

// Find GameObject by name

    GameObject MyGO = GameObject.Find("MyNamedGameObject");

    // オブジェクトをタイプ別に検索します
    MyComponent[] Components = Object.FindObjectsOfType(typeof(MyComponent)) as MyComponent[];
    foreach (MyComponent Component in Components)
    {
            // ...
    }

    // タグでGameObjectを検索します
    GameObject[] GameObjects = GameObject.FindGameObjectsWithTag("MyTag");
    foreach (GameObject GO in GameObjects)
    {
            // ...
    }

Unreal Engine C++

    // 名前でアクターを探します (UObjectでも動作します)
    AActor* MyActor = FindObject<AActor>(nullptr, TEXT("MyNamedActor"));

    // タイプでアクターを探します(UWorldオブジェクトが必要です。)
    for (TActorIterator<AMyActor> It(GetWorld()); It; ++It)
    {
            AMyActor* MyActor = *It;
            // ...
    }

ブループリント

image alt text

Unreal Engine C++

    // Find UObjects by type
    for (TObjectIterator<UMyObject> It; It; ++it)
    {
        UMyObject* MyObject = *It;
        // ...
    }

    // Find Actors by tag (also works on ActorComponents, use TObjectIterator instead)
    for (TActorIterator<AActor> It(GetWorld()); It; ++It)
    {
        AActor* Actor = *It;
        if (Actor->ActorHasTag(FName(TEXT("Mytag"))))
        {
            // ...
        }
    }

ブループリント

image alt text

ゲームオブジェクト / アクタにタグを追加する

Unity C#

    MyGameObject.tag = "MyTag";

Unreal Engine C++

    // Actors can have multiple tags
    MyActor.Tags.AddUnique(TEXT("MyTag"));

ブループリント

image alt text

MonoBehaviour / ActorComponent にタグを追加する

Unity C#

    // This changes the tag on the GameObject it is attached to
    MyComponent.tag = "MyTag";

Unreal Engine C++

    // Components have their own array of tags
    MyComponent.ComponentTags.AddUnique(TEXT("MyTag"));

ゲームオブジェクト / アクタと MonoBehaviour / ActorComponent のタグの比較

Unity C#

    if (MyGameObject.CompareTag("MyTag"))
    {
        // ...
    }

    // Checks the tag on the GameObject it is attached to
    if (MyComponent.CompareTag("MyTag"))
    {
        // ...
    }

Unreal Engine C++

    // Checks if an Actor has this tag
    if (MyActor->ActorHasTag(FName(TEXT("MyTag"))))
    {
        // ...
    }

ブループリント

image alt text

Unreal Engine C++

    // Checks if an ActorComponent has this tag
    if (MyComponent->ComponentHasTag(FName(TEXT("MyTag"))))
    {
        // ...
    }

ブループリント

image alt text

物理特性:リジッドボディとプリミティブ コンポーネント

Unity でゲームオブジェクトに物理特性を与えるには、まずリジッドボディ コンポーネントを与える必要があります。

Unreal Engine ではプリミティブ コンポーネント (C++ では UPrimitiveComponent) が物理オブジェクトになります。以下に一般的なプリミティブ コンポーネントを挙げます。

  • シェイプ コンポーネント (カプセル、球体、ボックス)

  • スタティック メッシュ コンポーネント

  • スケルタル メッシュ コンポーネント

コリジョンやビジュアライゼーションの役目が別々のコンポーネントに分かれている Unity とは異なり、Unreal Engine は「物理化」と「可視化」を 1 つのプリミティブ コンポーネントに組み合わせています。ワールドで形状を持ち、レンダリングされたり物理的な作用を受けたりするコンポーネントは、PrimitiveComponent のサブクラスです。

レイヤーとチャンネルの比較

Unreal Engine のコリジョン チャンネルは Unity のレイヤーに相当します。詳細については、「コリジョン フィルタリング」を参照してください。

レイ キャストとレイ トレースの比較

Unity C#

    GameObject FindGOCameraIsLookingAt()
    {
        Vector3 Start = Camera.main.transform.position;
        Vector3 Direction = Camera.main.transform.forward;
        float Distance = 100.0f;
        int LayerBitMask = 1 << LayerMask.NameToLayer("Pawn");

        RaycastHit Hit;
        bool bHit = Physics.Raycast(Start, Direction, out Hit, Distance, LayerBitMask);

        if (bHit)
        {
            return Hit.collider.gameObject;
        }

        return null;
    }

Unreal Engine C++

    APawn* AMyPlayerController::FindPawnCameraIsLookingAt()
    {
        // You can use this to customize various properties about the trace
        FCollisionQueryParams Params;
        // Ignore the player's pawn
        Params.AddIgnoredActor(GetPawn());

        // The hit result gets populated by the line trace
        FHitResult Hit;

        // Raycast out from the camera, only collide with pawns (they are on the ECC_Pawn collision channel)
        FVector Start = PlayerCameraManager->GetCameraLocation();
        FVector End = Start + (PlayerCameraManager->GetCameraRotation().Vector() * 1000.0f);
        bool bHit = GetWorld()->LineTraceSingle(Hit, Start, End, ECC_Pawn, Params);

        if (bHit)
        {
            // Hit.Actor contains a weak pointer to the Actor that the trace hit
            return Cast<APawn>(Hit.Actor.Get());
        }

        return nullptr;
    }

ブループリント

画像をクリックするとフルサイズで表示されます。

トリガー ボリューム

Unity C#

    public class MyComponent : MonoBehaviour
    {
        void Start()
        {
            collider.isTrigger = true;
        }
        void OnTriggerEnter(Collider Other)
        {
            // ...
        }
        void OnTriggerExit(Collider Other)
        {
            // ...
        }
    }

Unreal Engine C++

    UCLASS()
    class AMyActor : public AActor
    {
        GENERATED_BODY()

        // My trigger component
        UPROPERTY()
        UPrimitiveComponent* Trigger;

        AMyActor()
        {
            Trigger = CreateDefaultSubobject<USphereComponent>(TEXT("TriggerCollider"));

            // Both colliders need to have this set to true for events to fire
            Trigger.bGenerateOverlapEvents = true;

            // Set the collision mode for the collider
            // This mode will only enable the collider for raycasts, sweeps, and overlaps
            Trigger.SetCollisionEnabled(ECollisionEnabled::QueryOnly);
        }

        virtual void NotifyActorBeginOverlap(AActor* Other) override;

        virtual void NotifyActorEndOverlap(AActor* Other) override;
    };

Unreal Engine のブループリント

image alt text

コリジョン反応の設定の詳細については、「コリジョン」を参照してください。

キネマティック リジッドボディ

Unity C#

    public class MyComponent : MonoBehaviour
    {
        void Start()
        {
            rigidbody.isKinematic = true;
            rigidbody.velocity = transform.forward * 10.0f;
        }
    }

Unreal Engine 4 ではコリジョン コンポーネントとリジッドボディ コンポーネントが一つになっています。この基本クラスは UPrimitiveComponent で、ニーズに合うようたくさんのサブクラス (USphereComponentUCapsuleComponent など) があります。

Unreal Engine C++

    UCLASS()
    class AMyActor : public AActor
    {
        GENERATED_BODY()

        UPROPERTY()
        UPrimitiveComponent* PhysicalComp;

        AMyActor()
        {
            PhysicalComp = CreateDefaultSubobject<USphereComponent>(TEXT("CollisionAndPhysics"));
            PhysicalComp->SetSimulatePhysics(false);
            PhysicalComp->SetPhysicsLinearVelocity(GetActorRotation().Vector() * 100.0f);
        }
    };

入力イベント

Unity C#

    public class MyPlayerController : MonoBehaviour
    {
        void Update()
        {
            if (Input.GetButtonDown("Fire"))
            {
                // ...
            }
            float Horiz = Input.GetAxis("Horizontal");
            float Vert = Input.GetAxis("Vertical");
            // ...
        }
    }

Unreal Engine C++:

    UCLASS()
    class AMyPlayerController : public APlayerController
    {
        GENERATED_BODY()

        void SetupInputComponent()
        {
            Super::SetupInputComponent();

            InputComponent->BindAction("Fire", IE_Pressed, this, &AMyPlayerController::HandleFireInputEvent);
            InputComponent->BindAxis("Horizontal", this, &AMyPlayerController::HandleHorizontalAxisInputEvent);
            InputComponent->BindAxis("Vertical", this, &AMyPlayerController::HandleVerticalAxisInputEvent);
        }

        void HandleFireInputEvent();
        void HandleHorizontalAxisInputEvent(float Value);
        void HandleVerticalAxisInputEvent(float Value);
    };

ブループリント

image alt text

以下は、プロジェクト設定で入力プロパティがどのように表示されるかを示します。

Input settings in Unreal Engine

Unreal Engine プロジェクトの入力のセットアップ方法については、「Input」を参照してください。

FAQ

最後に使用したプロジェクトを自動的にロードするにはどうすればよいですか?

最後に使用したプロジェクトを起動時に自動的にロードするよう Unreal Engine を設定できます。Epic ランチャーからプロジェクトを開くときに、Unreal Engine スタート画面で [Always Lost Last Project on Startup (起動時に常に前回のプロジェクトを開く)] オプションを有効にしてください。

always-load-last-project-at-startup.png

ゲームの入力バインディングはどこで設定しますか?

Unity では、プロジェクトの入力マネージャー設定を使ってデフォルトのバインディングをセットアップします。

Unreal Engine では、[Project Settings] ウィンドウの [Input (入力)] カテゴリで入力バインディングを設定できます。このウィンドウにはさまざまなボタン (アクション) やアナログ コントロール (軸) があります。各コントロールに名前とデフォルトのバインディングを与えます。一度行うと、入力イベントがトリガーされたときに、ゲームのポーンに呼び出すことができます。

Unreal Engine プロジェクトの入力のセットアップ方法については、「Input」を参照してください。

プロジェクトの開始シーンを変更するにはどうすればよいですか?

デフォルトでは、Unreal Engine はプロジェクトを開くときにプロジェクトのデフォルト レベルをロードします。この動作は [Project Settings] ウィンドウ (メイン メニュー:[Edit] > [Project Settings]) の [General (全般)] > [Loading & Saving (ロードと保存)] カテゴリで変更できます。

ゲームを実行するにはどうすればよいですか?

ゲームを事前テスト (実行) するには以下のような方法があります。

  • Unreal Editor で直接実行する場合は、メイン ツールバー[Play (プレイ)] ボタンをクリックします。

  • スタンドアローン プロセスとして実行する場合は、メイン ツールバー[Platforms (プラットフォーム)] ボタンをクリックして、ドロップダウン リストからマシンを選択します。この方法では、まずプラットフォームに実行ファイルがビルドされます。たとえば Windows マシンで作業している場合、Windows 実行ファイルがビルドされます。

  • 別のプラットフォーム (モバイル デバイスや Web ブラウザなど) で実行する場合は、メイン ツールバー[Platforms] ボタンをクリックし、ゲームを実行するプラットフォームを選択します。必要な依存ファイルを最初にすべてインストールする必要があります。

Unreal Engine のゲームを別のプラットフォームで実行する場合の詳細については、以下のページを参照してください。

単位は何を使いますか?

Unity では計測の基本単位は 1 m です。Unreal Engine では計測の基本単位は 1 cm です。

そのため、Unity で 1 単位 (m) 動かす場合、Unreal Engine では100 単位 (cm) 動かすことになります。

Unity で 2 フィート動かすとすると 0.61 単位 (m) になります。Unreal Engine では61 単位 (cm) に相当します。

Unreal Engine の座標系はどの向きですか?

Unity も Unreal Engine も左手座標系を用いますが、軸の名前が異なります。Unreal Engine では X 軸正方向が「前」、Y 軸正方向が「右」、Z 軸正方向が「上」です。

ゲームのログ出力を確認するにはどうすればよいですか?

ボタン ツールバー[Output Log (アウトプット ログ)] ボタンをクリックしてください。

例外を投げるにはどうすればよいですか?

Unity とは異なり、Unreal Engine は例外処理を使用しません。代わりに check() 関数を使ってクリティカル アサーション エラーをトリガーします。エラー メッセージを渡すことができます。エラーを報告したいけれどもプログラムを停止したくない場合は、代わりに ensure() を使います。エラーを完全なコール スタックとともに記録しますが、プログラムの実行は継続されます。デバッガをアタッチしている場合は、どちらの関数もデバッガで停止します。

.NET フレームワークはどこにありますか?

Unity とは異なり、Unreal Engine は .NET フレームワークを使用しません。Unreal Engine にはコンテナ クラスとライブラリの独自のセットがあります。以下は一般的なコンテナの対応表です。

.NET フレームワーク

Unreal Engine

String

FStringFText

List

TArray

Dictionary

TMap

HashSet

TSet

Unreal Engine のその他のコンテナの詳細については こちら を参照してください。

Unreal Engine ではコード変更を自動的にリロードしますか?

はい。コード記述中にエディタを開いたままにできます。コード編集後に Visual Studio からコンパイルを開始すると、エディタが変更を自動的に「ホット リロード」します。

ヘルプと回答を検索する

ご覧いただきありがとうございます。本ガイドは当初、Unreal コミュニティ向けに世界中の Unreal Engine デベロッパーの支援により作成されましたが、今回それを Unreal Engine 5 用に更新しました。Unreal Engine への移行時に最も役立つ情報を検討しながら今後も改善を続けます。皆様のフィードバックや訂正をお待ちしております。

Unreal Engine の詳細については、本 Web サイトの他のドキュメントや以下の関連情報をご覧ください。

タグ
Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル