You've already forked UnrealEngineUWP
mirror of
https://github.com/izzy2lost/UnrealEngineUWP.git
synced 2026-03-26 18:15:20 -07:00
1072 lines
59 KiB
Plaintext
1072 lines
59 KiB
Plaintext
INTSourceChangelist:2468626
|
||
Availability:Public
|
||
Title:Unity 引っ越しガイド
|
||
Crumbs: %ROOT%, GettingStarted
|
||
Description:Unity の操作内容を UE4 の該当する部分と比較して説明し、UE4 の迅速な習得を支援します。
|
||
|
||
|
||

|
||
|
||
[TOC(start:2 end:2)]
|
||
|
||
|
||
## 概要
|
||
|
||
このガイドでは、Unity ユーザーの視点に立って UE4 の概要を説明します。これまでの Unity でのご経験を UE4 ワールドに移行する支援をします。
|
||
|
||
## エディタ
|
||
|
||
以下は Unity のエディタとアンリアル エディタの画面です。一般的な機能を表すために **色分け** されています。各ブロックには、該当する UE4 用語を示すラベルが付いています。アンリアル エディタのレイアウトは、タブをドラッグ & ドロップすることで完全にカスタマイズ可能です。
|
||
|
||

|
||
|
||
### アセットの編集
|
||
|
||
Unity では、インスペクター (Inspector) タブを使用してプロジェクト内で選択したアセットを編集します。UE4 では、**[詳細]** パネルに選択したオブジェクトのプロパティが表示されますが、編集タスクが大きい場合は、**専用のウィンドウやタブ** になります。編集した各アセットに対して新しくタブ化されたウィンドウが開きます。**ウェブ ブラウザと同様です。**当然、スタンドアロンのウィンドウとしてタブを自由にドラッグしたり、フロートさせたりできます。
|
||
|
||

|
||
|
||
## クイック用語集
|
||
|
||
以下のセクションでは、左側に一般的な Unity 用語を、右側にそれに相当する (またはほぼ同等の) UE4 用語を表示しています。UE4 のキーワードはアンリアル エンジンのオンライン ドキュメントの詳細情報に直接リンクしています。
|
||
|
||
| カテゴリ | Unity | UE4 |
|
||
| -------- | ----- | --- |
|
||
| **ゲームプレイ タイプ** | コンポーネント | [コンポーネント](Engine/Blueprints/UserGuide/Components) |
|
||
| | ゲームオブジェクト | [アクタ](Engine/Actors), [ポーン](Gameplay/Framework/Pawn) |
|
||
| | プレハブ | [ブループリント クラス](Engine/Blueprints) |
|
||
| **エディタ UI** | ヒエラルキー パネル | [ワールド アウトライナー](Engine/UI/LevelEditor#ワールドアウトライナー) |
|
||
| | インスペクター | [詳細パネル](Engine/UI/LevelEditor#詳細) |
|
||
| | プロジェクト ブラウザ | [コンテンツ ブラウザ](Engine/Content/Browser) |
|
||
| | シーンビュー | [ビューポート](Engine/UI/LevelEditor/Viewports) |
|
||
| **メッシュ** | メッシュ| [スタティックメッシュ](Engine/Actors/StaticMeshActor) |
|
||
| | スキンメッシュ | [スケルタルメッシュ](Engine/Content/Types/SkeletalMeshes) |
|
||
| **マテリアル** | シェーダ| [マテリアル](Engine/Rendering/Materials)、[マテリアル エディタ](Engine/Rendering/Materials/Editor) |
|
||
| | マテリアル | [マテリアル インスタンス](Engine/Rendering/Materials/MaterialInstances) |
|
||
| **エフェクト** | パーティクル エフェクト | [エフェクト、パーティクル、カスケード](Engine/Rendering/ParticleSystems) |
|
||
| | Shuriken (パーティクル システム) | [カスケード](Engine/Rendering/ParticleSystems) |
|
||
| **ゲーム UI** | UI | [UMG (アンリアル モーション グラフィックス)](Engine/UMG) |
|
||
| **アニメーション** | アニメーション| [スケルタル アニメーション システム](Engine/Animation) |
|
||
| | メカニム | [ペルソナ](Engine/Animation/Persona) , [アニメーション ブループリント](Engine/Animation/AnimBlueprints) |
|
||
| **2D** | スプライト エディター | [Paper2D](Engine/Paper2D) |
|
||
| **プログラミング** | C# | [C++](Programming) |
|
||
| | スクリプト | [ブループリント](Engine/Blueprints) |
|
||
| **物理** | レイキャスト | [Line Trace, Shape Trace](Gameplay/HowTo/UseRaycasts/Blueprints) |
|
||
| | リジッドボディ | [コリジョン、物理](Engine/Physics) |
|
||
| **実行時プラットフォーム** | iOS Player、Web Player | [プラットフォーム](Platforms) |
|
||
|
||
|
||
## プロジェクトとファイル
|
||
|
||
### ディレクトリやファイルは?
|
||
|
||
Unity プロジェクトと同様に Unreal プロジェクトは常に独自のディレクトリにあり、独自のプロジェクト ファイルを持ちます。**.uproject** ファイルを **ダブルクリック** して、ゲームをアンリアル エディタに読み込むか、**右クリック** してさらにオプションを見ることができます。プロジェクト フォルダには、ゲームのコンテンツ、ソース、様々なコンフィギュレーション ファイルやバイナリを入れる様々なサブフォルダがあります。最も重要なのは、 **Content ** と **Source ** サブフォルダです。
|
||
|
||
### アセットを入れる場所は?
|
||
|
||
UE4 では、各プロジェクトに **Content ** フォルダがあります。Unity プロジェクトのアセット フォルダと同様に、ここにゲーム アセットを格納します。ゲームにアセットをインポートするには、プロジェクトの Content ディレクトリにファイルをドロップすると、自動的にインポートされて **コンテンツ ブラウザ** に表示されます。外部プログラムを使用してファイルに変更を加えるとエディタ内のアセットは自動的に更新されます。
|
||
|
||

|
||
|
||
### サポートされる共通ファイル形式は?
|
||
|
||
Unity では幅広いファイル形式をサポートしています。UE4 では以下のように非常に一般的なファイル形式をサポートしています。
|
||
|
||
|
||
|アセット タイプ | サポートするファイル形式|
|
||
| --- | --- |
|
||
| 3D | .fbx, .obj |
|
||
| テクスチャ| .png, .jpeg, .bmp ,.tga, .dds, .exr, .psd, .hdr |
|
||
| サウンド | .wav |
|
||
| フォント | .ttf, .otf |
|
||
| ビデオ | .mov, .mp4, .wmv |
|
||
|
||
### シーンの保存方法は?
|
||
|
||
Unity では、GameObject をシーンに配置し、それを Scene アセット ファイルとして保存します。アンリアル エンジンには、Unity のシーンに類似する **マップ ファイル** があります。マップ ファイルには、**レベル** とその中のオブジェクトに関するデータだけでなく、ライティング データや一部のレベル固有の設定も格納されます。
|
||
|
||
### プロジェクト設定の変更方法は?
|
||
|
||
すべてのプロジェクト設定はメイン メニューの **Edit** (編集) / **Project Settings** (プロジェクト設定) にあります。Unity のプロジェクト設定と同様に、プロジェクトに関する情報 (プロジェクト名やアイコンなど) を指定できます。ゲームの入力バインディングを設定したり、プロジェクト実行時のエンジンの挙動を定義できます。個々のプロジェクト設定については [ここ](Engine/UI/ProjectSettings) をご覧ください。Unity には、「プレイヤー設定」と呼ばれるものもあります。アンリアルでは、「プラットフォーム設定」 (platform settings) に相当し、プロジェクト設定の「プラットフォーム」カテゴリにあります。
|
||
|
||
### ソース ファイルの行先は?
|
||
|
||
Unityでは、C# のソース ファイルをアセット フォルダに入れていました。
|
||
|
||
UE4 では違います。C++ コードを持つプロジェクトでは、プロジェクト ディレクトリの下に **Source** サブフォルダがあります。ここには、 C++ ソース (.cpp) ファイルおよびヘッダー (.h) ファイル、一部のビルド スクリプト (.Build.cs、.Target.cs) を含む様々なファイルが入ります。しかし、ブループリントだけのプロジェクトには Source フォルダはありません。
|
||
|
||
UE4 で C++ を使用して作業を開始する最も簡単な方法はエディタを使用して (メインのファイルメニューで) **Add Code to Project (プロジェクトにコードを追加)** するか、または単純に数多くあるテンプレートのひとつを使用して最初から C++ プロジェクトを新規作成します。**コンテンツ ブラウザ** の中で C++ クラスを見つけて、そのアイコンを **ダブル クリック** して Visual Studio または Xcode でファイルを開くことができます。
|
||
|
||
## ゲームオブジェクトからアクタへ
|
||
|
||
### ゲームオブジェクトはどこに?
|
||
|
||
Unity ではゲームオブジェクトはワールドに配置可能な「もの」でした。これに相当するものは UE4 ではアクタになります。アンリアル エディタでは、新しい Empty Actor (空のアクタ) を [Placement] パネルからビューポートにドラッグできます。
|
||
|
||
(convert:false)
|
||
|
||
Empty Actor からゲームをビルドできますが、UE4 には特殊なタイプのアクタとして、ビルトインされているポーン (プレイヤーまたはAI のオブジェクト用) やキャラクター (アニメートされたクリーチャー用) などがあります。Empty Actor と同様に、こうした特殊タイプのアクタをドロップして、プロパティやコンポーネントを追加したり、カスタマイズすることができます。後で詳しく説明しますが、ここでは UE4 には、これらの特殊なアクタを使って動作する [ゲームプレイのフレームワーク](Gameplay/Framework) があることを覚えておいてください。
|
||
|
||
UE4 のアクタは Unity の GameObject とは少々異なります。Unity では GameObject は直接拡張できない C# クラスです。UE4 ではアクタは C++ のクラスであり、継承を用いて拡張しカスタマイズできます。これについては後で詳しく説明します。
|
||
|
||
### コンポーネントはどこに?
|
||
|
||
Unity では、ゲームオブジェクトにコンポーネントを追加して機能を加えます。
|
||
|
||
UE4 では、アクタにコンポーネントを追加します。レベルに Empty Actor をドロップしたら、 (**[詳細]** パネルにある) [Add Component] ボタンをクリックして、追加するコンポーネントを選択します。ここでは、Empty Actor をドロップして、たいまつを作成し、ベースとしてメッシュ コンポーネントを追加し、続いて光源を、そしてパーティクル システムを追加し炎を作ります。
|
||
|
||
(convert:false)
|
||
|
||
Unity では、ゲームオブジェクトはコンポーネントのフラット リストを保持します。UE4 では、アクタは互いにアタッチされたコンポーネントの **階層** が実際にあります。これは、上の例を見るとわかります。ライトとパーティクルがメッシュにアタッチされています。これは、後で [複合アクタとゲームオブジェクト](#複合オブジェクト) で説明するいくつかの重要な内容を含みます。
|
||
|
||
### Unity のプレハブから UE4 のブループリント クラスへ
|
||
|
||
Unity のワークフローはプレハブに基づいています。Unity では、コンポーネントを用いてゲームオブジェクトのセットをビルドして、そこからプレハブを作ります。ワールドにプレハブのインスタンスを配置しておくか、実行時にインスタンス化することができます。
|
||
|
||
|
||
UE4 でこれに対応するワークフローはブループリント クラスに基づくものです。UE4 では、コンポーネント付きのアクタをビルドし、それを選択し、 ( **[詳細]** パネルで) ** [Blueprint / Add Script]** ボタンをクリックします。続いてブループリント クラスを保存する場所を選択して、**[Create Blueprint ]** をクリックして新しいブループリント クラスを保存します。
|
||
|
||
(convert:false)
|
||
|
||
新しいブループリント クラスは、 **コンテンツ ブラウザ** にあります。**ダブルクリック** して直接編集できます。またはどのレベルにでもドラッグ&ドロップできます。
|
||
|
||
### スクリプト コンポーネントと MonoBehaviour はどこに?
|
||
|
||
Unity では、ゲームオブジェクトにドロップし、C# スクリプティングを追加するスクリプティング コンポーネントがあります。MonoBehaviour から継承するクラスを作成し、そのコンポーネントが行うことを定義します。
|
||
|
||
UE4 にも類似したものがあります。全く新しいコンポーネント クラスを独自に作成し、アクタにドロップすることができます。ブループリント スクリプティングや C++ のいずれかを用いてコンポーネント クラスを作成できます。
|
||
|
||
UE4 で独自のコンポーネント クラスを作成するにはどうしたらよいでしょうか? **[詳細]** パネルの [Add Component] ドロップダウンで、新規コンポーネントを作成するか、既存のコンポーネントを選択できます。
|
||
|
||

|
||
|
||
Unity では、新規 MonoBehaviour を作成する場合、Start() 関数と Update() 関数を持つスケルトン クラス ファイルからプログラムを始めることができます。
|
||
|
||
UE4 でも InitializeComponent() 関数と TickComponent() を持つスケルトン クラスからプログラムを始めることができます。これらは、Start および Update と同様の機能を持っています。
|
||
|
||
ブループリント スクリプティング コンポーネントを作成すると、こうした関数と同じものが以下のようにビジュアル ノードとして用意されます。
|
||
|
||

|
||
|
||
### スクリプト可能な Actor ブループリント クラス
|
||
|
||
UE4 の優れた機能をご紹介します。新規 Actor ブループリント クラスは、独自のブループリント ビジュアル スクリプティングを持ちます。これにより、個々のコンポーネントだけでなく、オブジェクト全体にロジックを追加できます。継承と組み合わせると (以下で説明)、ゲーム デザインのフレキシビリティが非常に高くなります。
|
||
|
||
ビジュアル スクリプトをサポートするブループリント クラスに加えて、UE4 ではコードで実装された C++ クラスもサポートしています。以下は、Unity C#、UE4 C++、UE4 ブループリントです。
|
||
|
||
|
||
| Unity C# | UE4 C++ |
|
||
| --- | --- |
|
||
|[INCLUDE:GettingStarted/FromUnity#csharp_unity]| [INCLUDE:GettingStarted/FromUnity#cpp_ue4] |
|
||
|
||
|
||
<!--
|
||
[EXCERPT:csharp_Unity]
|
||
using UnityEngine;
|
||
using System.Collections;
|
||
|
||
public class MyComponent :MonoBehaviour
|
||
{
|
||
int Count;
|
||
|
||
// 初期化に使用します。
|
||
void Start ()
|
||
{
|
||
Count = 0;
|
||
}
|
||
|
||
// フレーム毎に更新が一回呼び出されます。
|
||
void Update ()
|
||
{
|
||
|
||
Count = Count + 1;
|
||
Debug.Log(Count);
|
||
}
|
||
}
|
||
[/EXCERPT:csharp_Unity]
|
||
|
||
[EXCERPT:cpp_UE4]
|
||
#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));
|
||
}
|
||
};
|
||
[/EXCERPT:cpp_UE4]
|
||
-->
|
||
|
||
|
||
| UE4 ブループリント |
|
||
| --- |
|
||
||
|
||
|
||
### UE4 のブループリント クラスは拡張可能
|
||
|
||
Unity のプレハブとUE4 のブループリント クラスは同じようにゲーム内でインスタンス化できます。しかし、Unity では他のプレハブ内にプレハブをネストすることで複雑になります。そのため、拡張可能な構成要素としては制約があります。
|
||
|
||
UE4 では、既存のブループリント クラスを拡張して、新規ブループリント クラスを作成し、新しいプロパティ、コンポーネント、ビジュアル スクリプト機能で強化します。
|
||
|
||
例えば、UE4 で、Monster という名前のブループリント クラスを作成するとします。このクラスに、人間を追いかけるなどのモンスターの基本機能を実装します。それを拡張するブループリント クラスをさらに作成できます。ドラゴン (火を吐く機能を追加したタイプのモンスター)、グルー (暗くなるとプレイヤーがその餌食になるかもしれないモンスター) など、他に 8 つあるとします。こうした Monster のサブクラスは Monster の基本機能を継承し、それに新しい機能を追加します。
|
||
|
||
Unity では、多くの異なる GameObject プレハブを作成して実装します。ひとつはドラゴン用、もうひとつはグルー用などです。例えば、すべてのモンスターに新しい機能を追加したいとします。新しい Speak コンポーネントを使用して会話機能を与えるなどです。Unity では、10 個のプレハブをすべて更新し、新しい機能を個別にコピーし、貼り付けなければなりません。
|
||
|
||
UE4 では、単に Monster ブループリント クラスを修正し、新しい会話機能を追加するだけです。本当にこれだけです。ドラゴン、グルー、その他 8 つの他のモンスターのサブクラスは新しい会話機能を自動的に継承し、これらに手を加える必要はありません。
|
||
|
||
まだまだ素晴らしいことがあります。ここでブループリント クラスに関して言及したことは、 C++ クラスにも同様にあてはまり、アクタやコンポーネントでも同じことが言えます。こうしたシステムは、拡張機能の大規模な開発に対応するように設計されています。数十名、数百名という開発者を抱えるプロジェクトに合わせて調整できます。
|
||
|
||
### ブループリント スクリプティング、C++ のどちらを使用するのか、それとも両方使用するのか?
|
||
|
||
ブループリントのビジュアル スクリプティングは、ゲーム内の単純な論理フローやアクションの順序付けに理想的なものです。デザイナー、アーティスト、ビジュアル指向のプログラマにとって素晴らしいシステムです。ゲーム内のオブジェクトに簡単にアクセスし、視覚的に制御できるからです。ブループリントだけを使用して小さなスタンドアロンのゲームを作ることだってできます。本格的な例として Tappy Chicken のサンプルをご覧ください。
|
||
|
||
C++ プログラミングは大規模タスク用です。ゲームプレイ システム、複雑な AI、新しいエンジン機能などがこれに該当します。既に何らかの C++ のご経験がありましたら、 [UE4 におけるC++ プログラミングの基礎](Programming/Basics) のページをご覧ください。
|
||
|
||
ほとんどのプロジェクトでは、ブループリントと C++ を合わせて使用することでしょう。多くの開発者は、ブループリントを使用してゲームの機能のプロトタイプを作ります。ブループリントはとても簡単で楽しいものだからです。後でパフォーマンスやエンジニアリングの精度を上げるために一部またはすべてを C++ に移動します。
|
||
|
||
###ブループリント クラスは C++ クラスを拡張可能
|
||
|
||
UE4 ゲーム開発の素晴らしさは、プログラマが C++ で新規機能を実装し、デザイナーとアーティストがその新規機能をブループリントで利用して、プログラマに更なる機能を求めるという相互作用にあります。以下は、ピックアップ システムを実装する UE4 ベースのシューティング ゲームをあるチームが構築するのに、C++ クラスのシステム プログラミングに、挙動と外観のための ブループリント クラスを混在させて使用した例です。
|
||
|
||

|
||
|
||
### Transform コンポーネント
|
||
|
||
Unity では各ゲーム オブジェクトには Transform コンポーネントがあります。これは、ゲームオブジェクト にワールドでの位置、回転、スケールを与えます。
|
||
|
||
同様に UE4 には、アクタにはシーン コンポーネントのどのサブクラスにもなりうる **ルート コンポーネント** があります。**シーン コンポーネント** は、アクタにワールド内での位置、回転、スケールを与えます。これは、その配下にあるすべてのコンポーネントに階層的に適用されます。使用する多くのコンポーネントは、シーン コンポーネントのサブクラスです。位置を持つのに非常に便利だからです。
|
||
|
||
Empty Actor を配置した場合でも、UE4 はそのアクタに対する「デフォルト シーン ルート」を作成します。これは、単にシンプルなシーン コンポーネントです。独自の新しいシーン コンポーネントをドロップすると、デフォルト シーン ルートを置き換えます。
|
||
|
||
### 複合オブジェクト
|
||
|
||
Unity では、以下のようにゲームオブジェクトの階層を構築し、transform (変換行列) を親子付けします。
|
||
|
||

|
||
|
||
UE4 では、以下のようにコンポーネントの階層をネストして複合ゲーム オブジェクトを作ります。
|
||
|
||

|
||
|
||
図からわかるように、ネストした階層はシーン コンポーネントを互いにアタッチして作ることができます。Unity で親子にする transform と同じような transform を持つからです。アクタ コンポーネント (すべてのクラスの基底クラス) は、アクタそのものだけに直接アタッチすることができます。
|
||
|
||
### コンポーネントから何もかもビルドするのでしょうか?
|
||
|
||
ユーザー次第ですが、ほとんどの場合、カスタム コンポーネント タイプとこうしたコンポーネントを使用するアクタ クラスを組み合わせて使用しています。しかし、前述のように UE4 には、ある程度の機能を持つ特殊なタイプのアクタが数多くあり、常にいくつかのコンポーネントが含まれています。例えば、**Character** には常に **Character Movement コンポーネント** が含まれます。
|
||
|
||
エンジン内ですぐに見つかるサブクラス化されたアクタ タイプがいくつかあり、ほぼすべてのタイプのゲームで役立ちます。以下は、非常に一般的なビルトイン アクタのリストです。
|
||
|
||
* **ポーン** - アクタの一種で、制御可能なゲーム オブジェクトを表します。通常、プレイヤーのアバターです。プレイヤーおよび同様に AI は、所有しているコントローラを通してポーンを動かします。
|
||
|
||
* **キャラクター** - 二足動物のアバター用にデザインされたポーンの特殊バージョンであり、こうしたゲーム オブジェクトの複雑さに対処します。
|
||
|
||
* **コントローラー** - ポーンを所有し制御します。ポーンをコントローラーから分離することで、プレイヤーが使用するのと同じインターフェースを使用してポーンを操作できる AI コントローラーを記述することができます。
|
||
|
||
* **プレイヤー コントローラー** - プレイヤーのゲームパッド、タッチ、マウス/キーボードから入力を受け、その入力を使用して所有するポーンまたはキャラクタを動かすように設計された特殊なコントローラーです。
|
||
|
||
### 何もかもがアクタということでしょうか?
|
||
|
||
いいえ、違います。**アクタ** は、UE4 でのゲームプレイに使用される非常に一般的なクラスであり、**ワールド** に **スポーン** できる唯一のタイプです。そのため、レベルに配置するものは何でもアクタになります。
|
||
|
||
もうひとつ理解すべき重要なタイプは、**オブジェクト** です。オブジェクトは実際に **アクタ** やその他多くのものを含むすべてのアンリアル クラスの基底クラスです。これはアクタよりもはるかに低レベルの構造体ですが、**反射** や **シリアル化** といったアンリアル クラスで求められる機能を持っています。オブジェクトは、**アクタ** の型にはまらない新しいタイプを定義する必要がある場合に使用する非常に基本的なクラスです。例えば、**アクタ コンポーネント** はすべてのコンポーネントの基底クラスであり、**アクタ** の代わりに **オブジェクト** から派生します。
|
||
|
||
### UE4 のゲームプレイ フレームワークはどのようなものですか?
|
||
|
||
そうですね、ここから話が少々すごいことになります (良い意味で)。Unity では、ゲーム デザインを開始するための白紙の状態があります。アンリアルでも同様です。Unityでは、基本的なゲームオブジェクトとコンポーネントから何もかもを構築できます。一方、アンリアルではアクタとコンポーネントからすべてのものを構築できます。
|
||
|
||
しかし、アンリアルにはこれに加えて [ゲームプレイ フレームワーク](Gameplay/Framework) と呼ばれる追加のレイヤーがあります。これは Unity には全く存在しません。アンリアル エンジンでこれを使用しなくてもかまいませんが、実に素晴らしいものです。基本的に、基本的なプリミティブ クラスを使用し、定められた決まりに従うと、いくつかの優れた機能が自動的に取得されます。自動取得しなければ、こうした機能は、実装や改良が非常に難しいものです (フル マルチプレイヤー サポートなど)。
|
||
|
||
数えきれない素晴らしいゲームがアンリアルのゲームプレイ フレームワークで設計されてきました。多少の時間を費やしても、この仕組みを理解する価値はあります。もちろん、独自のやり方で開始することもできるでしょう。それがお望みならば全く問題ありません。 しかし、何百もの優れたアンリアルを使った開発者が、UE4 のこのフレームワークをうまく活用してきました。だから、少し時間をかけて学ぶ価値はあります。
|
||
|
||
ゲームプレイ フレームワークを使用するには、アンリアル エンジンにあるカスタマイズされたビルトインのアクタ クラスについて学習する必要があります。こうしたクラスには、**ポーン**、 **キャラクター** および **プレイヤー コントローラ** があり、最終的にはレプリケーションとネットワーク機能の仕組みを理解する必要があります。しかし、ここでは基本に戻ります。
|
||
|
||
## UE4 でコードを記述する方法
|
||
|
||
### MonoDevelop<6F> でプログラミングするのには慣れているのですが...
|
||
|
||
ブループリント スクリプティングでは、アンリアル エディタさえあれば大丈夫です。何もかもがビルトインされています。C++ でコードを記述するには、Windows の場合は [Visual Studio の無料バージョン](http://go.microsoft.com/fwlink/?LinkId=525621) を、Mac の場合は [Xcode のインストール](https://itunes.apple.com/us/app/xcode/id497799835?mt=12) をダウンロードしてください。初めて新規プロジェクトを作成する場合 (または既存プロジェクトにコードを追加する場合)、UE4 では **Visual Studio プロジェクト ファイルを自動的に作成** します。Visual Studio を開くには以下の手順に従います。**コンテンツ ブラウザ** 内で C++ クラスを **ダブルクリック** するか、メイン ファイル メニューで [Open Visual Studio] をクリックします。
|
||
|
||

|
||
|
||
UE4 でのひとつの重要な違い: Visual Studio **プロジェクト ファイル** を手動でリフレッシュしなければならない場合があるでしょう (例、UE4 の新バージョンのダウンロード後、またはディスク上でソース ファイルの場所を手動で変更する場合)。手動リフレッシュを行うには、メイン メニューで "Refresh Visual Studio Project" をクリックするか、プロジェクト ディレクトリにある **.uproject file** 上で **右クリック** します。
|
||
|
||

|
||
|
||
### イベント関数 (Start、Update、など) の記述
|
||
|
||
MonoBehaviours での作業に馴染みのある場合、Start、Update、OnDestroy などのメソッドに慣れていることでしょう。以下は Unity の挙動とそれに相当する UE4 のアクタとコンポーネントを比較したものです。
|
||
|
||
Unity では、以下のような単純なコンポーネントがあるでしょう。
|
||
|
||
public class MyComponent :MonoBehaviour
|
||
{
|
||
void Start() {}
|
||
void OnDestroy() {}
|
||
void Update() {}
|
||
}
|
||
|
||
|
||
しかし、UE4 では新規コンポーネント タイプだけをコーディングするのではなく、**アクタそのものに対して** コードを記述できます。これは実際、非常に一般的であり、便利です。
|
||
|
||
Unity の Start、OnDestroy、および Update の関数と同様に、以下のように UE4 には類似のアクタのメソッド一式があります。
|
||
|
||
**C++** :
|
||
UCLASS()
|
||
class AMyActor : public AActor
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
// ゲーム開始時に呼び出されます。
|
||
void BeginPlay();
|
||
// 破壊時に呼び出されます。
|
||
|
||
void EndPlay(const EEndPlayReason::Type EndPlayReason);
|
||
|
||
// アクタを更新するためにフレーム毎に呼び出されます。
|
||
void Tick(float DeltaSeconds);
|
||
};
|
||
|
||
**ブループリント** :
|
||
|
||

|
||
|
||
UE4 のコンポーネントには異なる関数が含まれます。以下は単純な例です。
|
||
|
||
**C++** :
|
||
UCLASS()
|
||
class UMyComponent : public UActorComponent
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
// 所有するアクタの作成後に呼び出されます。
|
||
void InitializeComponent();
|
||
|
||
// コンポーネントまたは所有しているアクタが破壊されていると呼び出されます。
|
||
void UninitializeComponent();
|
||
|
||
//ティックのコンポーネント バージョン
|
||
void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction);
|
||
};
|
||
|
||
**ブループリント** :
|
||
|
||

|
||
|
||
|
||
UE4 では、メソッドの親クラスのバージョンを呼び出すことが重要です。
|
||
|
||
例えば、Unity の C# では、これは base.Update() で呼び出します。しかし、UE4 の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 クラスではないものに使用されます。
|
||
|
||
## UE4 でゲームプレイ コードを記述する方法
|
||
|
||
ここから少し詳しく掘り下げていきます。ゲーム制作において重要なプログラミングのトピックについて説明します。Unity をご存じであるため、アンリアル エンジンの C++ を学習する C# ユーザー向けに機能を説明しますが、お望みであればブループリント スクリプティングを使用してほぼすべてのことができます。可能な限り、C++ とブループリントの両方の例を加えました。
|
||
|
||
非常に一般的なゲームプレイ プログラミング パターンとアンリアル エンジンでの手法について説明します。Unity の多くの関数に対して、それに相当する馴染みのある関数がアンリアル エンジンにもあります。一般的な関数をひとつずつ説明していきます。
|
||
|
||
### ゲームオブジェクトのインスタンス化 / アクタのスポーン
|
||
|
||
Unity では、インスタンス化する関数を使用してオブジェクトの新しいインスタンスを作成します。
|
||
|
||
この関数は任意の UnityEngine.Object 型 (GameObject、 MonoBehaviour など) を引数に取り、コピーを作ります。
|
||
|
||
public GameObject EnemyPrefab;
|
||
public Vector3 SpawnPosition;
|
||
public Quaternion SpawnRotation;
|
||
|
||
void Start()
|
||
{
|
||
GameObject NewGO = (GameObject)Instantiate(EnemyPrefab, SpawnPosition, SpawnRotation);
|
||
NewGO.name = "MyNewGameObject";
|
||
}
|
||
|
||
UE4 では、オブジェクトをインスタンス化するニーズに応じて異なる 2 つの関数があります。NewObject を使用して新しい UObject タイプを作成します。SpawnActor を使用して AActor タイプをスポーンします。
|
||
|
||
最初に、UObjects と NewObject について簡単に説明します。アンリアル エンジンで UObject をサブクラス化することは、Unity で ScriptableObject をサブクラス化するのと非常に似ています。ワールドにスポーンする必要がない、またはアクタのようにアタッチされたコンポーネントを持つゲームプレイ クラスで役立ちます。
|
||
|
||
Unity では、ScriptableObject の独自のサブクラスを作成した場合、以下のようにインスタンス化できます。
|
||
|
||
MyScriptableObject NewSO = ScriptableObject.CreateInstance<MyScriptableObject>();
|
||
|
||
アンリアル エンジンでは、独自の UObject 派生型を作成した場合、以下のようにインスタンス化できます。
|
||
|
||
UMyObject* NewObj = NewObject<UMyObject>();
|
||
|
||
アクタはどうでしょう?アクタは、World (C++ の UWorld) オブジェクトで SpawnActor メソッドを使用してスポーンされます。World オブジェクトはどのように取得しますか?一部の UObjects は、GetWorld メソッドを提供します。例えば、すべてのアクタがそうです。
|
||
|
||
別のアクタを渡す代わりに、スポーンしたいアクタの「クラス」を渡すことに注意してください。この例では、クラスは AMyEnemy の任意のサブクラスになります。
|
||
|
||
しかし、インスタンス化で可能なように、別のオブジェクトの「コピー」を作りたい場合はどうでしょう?
|
||
|
||
NewObject 関数と SpawnActor 関数も一緒に動作する「テンプレート」オブジェクトがあります。アンリアル エンジンでは「ゼロから」作るかわりにそのオブジェクトのコピーを作ります。これにより、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);
|
||
}
|
||
|
||
この文脈で、「ゼロから」が何を意味するか疑問に思われるかもしれません。作成する各オブジェクト クラスはデフォルトのテンプレートを持ちます。このテンプレートには、プロパティとコンポーネントのデフォルト値があります。こうしたプロパティをオーバーライドせず、独自のテンプレートを提供しなければ、アンリアル エンジンはこうしたデフォルト値を使用してオブジェクトを作ります。わかりやすくするために、例えば、まず MonoBehaviour を見てみます。
|
||
|
||
public class MyComponent :MonoBehaviour
|
||
{
|
||
public int MyIntProp = 42;
|
||
public SphereCollider MyCollisionComp = null;
|
||
|
||
void Start()
|
||
{
|
||
//まだなければ、コリジョン コンポーネントを作成します。
|
||
if (MyCollisionComp == null)
|
||
{
|
||
MyCollisionComp = gameObject.AddComponent<SphereCollider>();
|
||
MyCollisionComp.center = Vector3.zero;
|
||
MyCollisionComp.radius = 20.0f;
|
||
}
|
||
}
|
||
}
|
||
|
||
上の例では、デフォルトで 42 になっている int プロパティと、デフォルトで半径 20 になっている SphereCollider コンポーネントがあります。
|
||
|
||
アンリアル エンジンでもオブジェクトのコンストラクタを使用して同じことを行うことができます。
|
||
|
||
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)
|
||
{
|
||
// ...
|
||
}
|
||
|
||
UE4 C++:
|
||
|
||
UPrimitiveComponent* Primitive = MyActor->GetComponentByClass(UPrimitiveComponent::StaticClass());
|
||
USphereComponent* SphereCollider = Cast<USphereComponent>(Primitive);
|
||
if (SphereCollider != nullptr)
|
||
{
|
||
// ...
|
||
}
|
||
|
||
#### ゲームオブジェクト / アクタを破壊する
|
||
|
||
[REGION:tablethird]
|
||
| Unity | C++ | ブループリント|
|
||
| --- | --- | --- |
|
||
|[INCLUDE:GettingStarted/FromUnity#gameobject_unity]| [INCLUDE:GettingStarted/FromUnity#gameobject_cpp] | [INCLUDE:GettingStarted/FromUnity#gameobject_bp] |
|
||
[/REGION]
|
||
|
||
<!--
|
||
[EXCERPT:gameObject_Unity]
|
||
Destroy(MyGameObject);
|
||
[/EXCERPT:gameObject_Unity]
|
||
|
||
[EXCERPT:gameObject_CPP]
|
||
MyActor->Destroy();
|
||
[/EXCERPT:gameObject_CPP]
|
||
|
||
[EXCERPT:gameObject_bp]
|
||

|
||
[/EXCERPT:gameObject_bp]
|
||
-->
|
||
|
||
|
||
|
||
|
||
#### ゲームオブジェクト / アクタを (1 秒後に) 破棄する
|
||
|
||
|
||
[REGION:tablethird]
|
||
| Unity | C++ | ブループリント|
|
||
| --- | --- | --- |
|
||
|[INCLUDE:GettingStarted/FromUnity#destroy_unity]| [INCLUDE:GettingStarted/FromUnity#destroy_cpp] | [INCLUDE:GettingStarted/FromUnity#destroy_bp] |
|
||
[/REGION]
|
||
|
||
<!--
|
||
[EXCERPT:destroy_Unity]
|
||
Destroy(MyGameObject, 1);
|
||
[/EXCERPT:destroy_Unity]
|
||
|
||
[EXCERPT:destroy_CPP]
|
||
MyActor->SetLifeSpan(1);
|
||
[/EXCERPT:destroy_CPP]
|
||
|
||
[EXCERPT:destroy_bp]
|
||
[REGION:lightbox]
|
||
[(w:240)](image_24.png)
|
||
[/REGION:lightbox]
|
||
|
||
_クリックしてフルサイズで表示_
|
||
[/EXCERPT:destroy_bp]
|
||
-->
|
||
|
||
|
||
#### ゲームオブジェクト / アクタを無効にする
|
||
|
||
|
||
[REGION:tablethird]
|
||
| Unity | C++ | ブループリント|
|
||
| --- | --- | --- |
|
||
|[INCLUDE:GettingStarted/FromUnity#disable_unity]| [INCLUDE:GettingStarted/FromUnity#disable_cpp] | [INCLUDE:GettingStarted/FromUnity#disable_bp] |
|
||
[/REGION]
|
||
|
||
<!--
|
||
[EXCERPT:disable_Unity]
|
||
MyGameObject.SetActive(false);
|
||
[/EXCERPT:disable_Unity]
|
||
|
||
[EXCERPT:disable_CPP]
|
||
// 表示されているコンポーネントを非表示にします。
|
||
MyActor->SetActorHiddenInGame(true);
|
||
|
||
// コリジョンを無効にします。
|
||
MyActor->SetActorEnableCollision(false);
|
||
|
||
// アクタのティックを停止します。
|
||
MyActor->SetActorTickEnabled(false);
|
||
[/EXCERPT:disable_CPP]
|
||
|
||
[EXCERPT:disable_bp]
|
||
[REGION:lightbox]
|
||
[(w:120)](image_25.png)
|
||
[/REGION]
|
||
|
||
_クリックしてフルサイズで表示_
|
||
[/EXCERPT:disable_bp]
|
||
-->
|
||
|
||
#### コンポーネントからゲームオブジェクト / アクタにアクセスする
|
||
|
||
|
||
[REGION:tablethird]
|
||
| Unity | C++ | ブループリント|
|
||
| --- | --- | --- |
|
||
| [INCLUDE:GettingStarted/FromUnity#go1_unity] | [INCLUDE:GettingStarted/FromUnity#go1_cpp] | [INCLUDE:GettingStarted/FromUnity#go1_bp] |
|
||
[/REGION]
|
||
|
||
<!--
|
||
[EXCERPT:go1_Unity]
|
||
GameObject ParentGO =
|
||
MyComponent.gameObject;
|
||
[/EXCERPT:go1_Unity]
|
||
|
||
[EXCERPT:go1_CPP]
|
||
AActor* ParentActor =
|
||
MyComponent->GetOwner();
|
||
[/EXCERPT:go1_CPP]
|
||
|
||
[EXCERPT:go1_bp]
|
||
[REGION:lightbox]
|
||
[(w:220)](image_32.png)
|
||
[/REGION]
|
||
_クリックしてフルサイズで表示_
|
||
[/EXCERPT:go1_bp]
|
||
-->
|
||
|
||
|
||
#### ゲームオブジェクト / アクタからコンポーネントにアクセスする
|
||
|
||
<!--
|
||
| メソッド | 説明 |
|
||
| --- | --- |
|
||
| Unity | [INCLUDE:GettingStarted/FromUnity#go2_unity]|
|
||
| C++ | [INCLUDE:GettingStarted/FromUnity#go2_cpp] |
|
||
| ブループリント | [INCLUDE:GettingStarted/FromUnity#go2_bp] |
|
||
-->
|
||
|
||
**Unity**
|
||
MyComponent MyComp = gameObject.GetComponent<MyComponent>();
|
||
|
||
**C++**
|
||
UMyComponent* MyComp = MyActor->FindComponentByClass<UMyComponent>();
|
||
|
||
**ブループリント**
|
||
|
||

|
||
|
||
|
||
|
||
|
||
|
||
|
||
<!--
|
||
[EXCERPT:go2_Unity]
|
||
MyComponent MyComp = gameObject.GetComponent<MyComponent>();
|
||
[/EXCERPT:go2_Unity]
|
||
|
||
[EXCERPT:go2_CPP]
|
||
UMyComponent* MyComp = Cast<UMyComponent>(MyActor->GetComponentByClass(UMyComponent::StaticClass()));
|
||
[/EXCERPT:go2_CPP]
|
||
|
||
[EXCERPT:go2_bp]
|
||
[REGION:lightbox]
|
||
[(w:220)](image_33.png)
|
||
[/REGION]
|
||
_クリックしてフルサイズで表示_
|
||
[/EXCERPT:go2_bp]
|
||
-->
|
||
|
||
|
||
#### ゲームオブジェクト / アクタの検索
|
||
|
||
// GameObject を名前で検索します。
|
||
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)
|
||
{
|
||
// ...
|
||
}
|
||
|
||
// アクタを名前で検索します (UObjects でも機能します)。
|
||
AActor* MyActor = FindObject<AActor>(nullptr, TEXT("MyNamedActor"));
|
||
|
||
// アクタをタイプで検索します (UWorld オブジェクトが必要です)。
|
||
for (TActorIterator<AMyActor> It(GetWorld()); It; ++It)
|
||
{
|
||
AMyActor* MyActor = *It;
|
||
// ...
|
||
}
|
||
|
||
(w:720)
|
||
|
||
// UObjects をタイプで検索します。
|
||
for (TObjectIterator<UMyObject> It; It; ++it)
|
||
{
|
||
UMyObject* MyObject = *It;
|
||
// ...
|
||
}
|
||
|
||
// アクタをタグで検索します (ActorComponents でも機能し、代わりにTObjectIterator を使用します)。
|
||
for (TActorIterator<AActor> It(GetWorld()); It; ++It)
|
||
{
|
||
AActor* Actor = *It;
|
||
if (Actor->ActorHasTag(FName(TEXT("Mytag"))))
|
||
{
|
||
// ...
|
||
}
|
||
}
|
||
|
||
(w:900)
|
||
|
||
#### ゲームオブジェクト / アクタにタグを追加する
|
||
|
||
MyGameObject.tag = "MyTag";
|
||
|
||
// アクタは複数のタグを持つことができます。
|
||
MyActor.Tags.AddUnique(TEXT("MyTag"));
|
||
|
||
(w:540)
|
||
|
||
#### MonoBehaviours / ActorComponents にタグを追加する
|
||
|
||
// アタッチされている GameObject のタグを変更します。
|
||
MyComponent.tag = "MyTag";
|
||
|
||
// コンポーネントは独自のタグの配列を持ちます。
|
||
MyComponent.ComponentTags.AddUnique(TEXT("MyTag"));
|
||
|
||
#### ゲームオブジェクト / アクタと MonoBehaviours / ActorComponents のタグを比較する
|
||
|
||
if (MyGameObject.CompareTag("MyTag"))
|
||
{
|
||
// ...
|
||
}
|
||
|
||
// アタッチされているゲームオブジェクトのタグをチェックします。
|
||
if (MyComponent.CompareTag("MyTag"))
|
||
{
|
||
// ...
|
||
}
|
||
//アクタがこのタグを持っているかをチェックします。
|
||
|
||
if (MyActor->ActorHasTag(FName(TEXT("MyTag"))))
|
||
{
|
||
// ...
|
||
}
|
||
|
||
(w:540)
|
||
|
||
// ActorComponent がこのタグを持っているかをチェックします。
|
||
if (MyComponent->ComponentHasTag(FName(TEXT("MyTag"))))
|
||
{
|
||
// ...
|
||
}
|
||
|
||
(w:700)
|
||
|
||
### 物理:RigidBody vs. Primitive Component
|
||
|
||
Unity では、ゲームオブジェクトに物理特性を与えるために、まず RigidBody コンポーネントを追加します。アンリアル エンジンでは、任意の Primitive コンポーネント (C++ では UPrimitiveComponent ) が物理オブジェクトになります。一般的な Primitive コンポーネントとして、ShapeComponents (カプセル、球、ボックス)、StaticMeshComponent、および SkeletalMeshComponent があります。
|
||
|
||
Unity とは異なります。Unity では、コリジョンとビジュアル化の役割は別のコンポーネントに分かれています。アンリアル エンジンでは、物理とビジュアルの概念を PrimitiveComponent に組み合わせています。ワールドでジオメトリを持つコンポーネントはレンダリングされるか、PrimitiveComponent のサブクラスと物理的に相互作用します。
|
||
|
||
### レイヤー vs チャンネル
|
||
|
||
Unity では、「レイヤー」と呼ばれます。UE4 では、コリジョン チャンネルを使用し、同様に機能します。こうした情報については、[ここ](https://www.unrealengine.com/blog/collision-filtering) をご覧ください。
|
||
|
||
### レイキャスト vs レイトレース
|
||
|
||
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;
|
||
}
|
||
|
||
UE4 C++:
|
||
|
||
APawn* AMyPlayerController::FindPawnCameraIsLookingAt()
|
||
{
|
||
// これを使ってトレースに関する様々なプロパティをカスタマイズできます。
|
||
FCollisionQueryParams Params;
|
||
// プレイヤーのポーンを無視します。
|
||
Params.AddIgnoredActor(GetPawn());
|
||
|
||
// ライントレースによって当たった結果が追加されます。
|
||
FHitResult Hit;
|
||
|
||
// カメラからのレイキャストです。ポーンとのみ衝突します (ECC_Pawn のコリジョン チャンネルにあります)。
|
||
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 にはトレースが当たるアクタへの弱いポインタがあります。
|
||
return Cast<APawn>(Hit.Actor.Get());
|
||
}
|
||
|
||
return nullptr;
|
||
}
|
||
|
||
UE4 ブループリント:
|
||
[REGION:lightbox]
|
||
[(w:700)](image_19.png)
|
||
[/REGION]
|
||
|
||
_クリックしてフルサイズで表示_
|
||
|
||
### トリガー
|
||
|
||
Unity C#:
|
||
|
||
public class MyComponent :MonoBehaviour
|
||
{
|
||
void Start()
|
||
{
|
||
collider.isTrigger = true;
|
||
}
|
||
void OnTriggerEnter(Collider Other)
|
||
{
|
||
// ...
|
||
}
|
||
void OnTriggerExit(Collider Other)
|
||
{
|
||
// ...
|
||
}
|
||
}
|
||
|
||
UE4 C++:
|
||
|
||
UCLASS()
|
||
class AMyActor : public AActor
|
||
{
|
||
GENERATED_BODY()
|
||
|
||
// My trigger component
|
||
UPROPERTY()
|
||
UPrimitiveComponent* Trigger;
|
||
|
||
AMyActor()
|
||
{
|
||
Trigger = CreateDefaultSubobject<USphereComponent>(TEXT("TriggerCollider"));
|
||
|
||
// イベントを発行するには、両方のコライダーでこれを true に設定する必要があります。
|
||
Trigger.bGenerateOverlapEvents = true;
|
||
|
||
// コライダーのコリジョン モードを設定します。
|
||
// このモードはレイキャスト、スイープ、オーバーラップのコライダーだけを有効にします。
|
||
Trigger.SetCollisionEnabled(ECollisionEnabled::QueryOnly);
|
||
}
|
||
|
||
void BeginPlay()
|
||
{
|
||
// 重なりを見つけるために登録します。
|
||
OnActorBeginOverlap.AddDynamic(this, &AMyActor::OnTriggerEnter);
|
||
OnActorEndOverlap.AddDynamic(this, &AMyActor::OnTriggerExit);
|
||
|
||
Super::BeginPlay();
|
||
}
|
||
|
||
void EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||
{
|
||
OnActorBeginOverlap.RemoveDynamic(this, &AMyActor::OnTriggerEnter);
|
||
OnActorEndOverlap.RemoveDynamic(this, &AMyActor::OnTriggerExit);
|
||
|
||
Super:EndPlay(EndPlayReason);
|
||
}
|
||
|
||
UFUNCTION()
|
||
void OnTriggerEnter(AActor* Other);
|
||
|
||
UFUNCTION()
|
||
void OnTriggerExit(AActor* Other);
|
||
};
|
||
|
||
UE4 ブループリント:
|
||
|
||

|
||
|
||
コリジョン応答の設定についての詳しい情報については、[ここ](Engine/Physics/Collision) をご覧ください。
|
||
|
||
### キネマティック リジッドボディ
|
||
|
||
Unity C#:
|
||
|
||
public class MyComponent :MonoBehaviour
|
||
{
|
||
void Start()
|
||
{
|
||
rigidbody.isKinimatic = true;
|
||
rigidbody.velocity = transform.forward * 10.0f;
|
||
}
|
||
}
|
||
|
||
UE4 では、コリジョン コンポーネントと rigidbody (剛体) コンポーネントはひとつです。これに対する基本クラスは、UPrimitiveComponent であり、ニーズに合うように多くのサブクラスがあります (USphereComponent、 UCapsuleComponent など)。
|
||
|
||
UE4 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");
|
||
// ...
|
||
}
|
||
}
|
||
|
||
UE4 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);
|
||
};
|
||
|
||
UE4 ブループリント:
|
||
|
||

|
||
|
||
以下は、Project Settings (プロジェクト設定) で入力プロパティがどのように見えるかを表しています。
|
||
|
||

|
||
|
||
入力のセットアップ方法の詳しい情報は、[ここ](Gameplay/Input) をご覧ください。
|
||
|
||
## FAQ
|
||
|
||
### 最後に作業したプロジェクトを自動的にロードする方法は?
|
||
|
||
Unity で最後に作業したプロジェクトを自動的にロードすることに慣れている場合、UE4 でも同じようにできます。これを有効にするには、プロジェクトを開くときに、 "Always load last project on Startup" (最後に使用したプロジェクトを起動時に常にロードする) にチェックを入れてください。メインの Edit メニューの Edit/Editor Preferences/Loading and Saving/Startup でいつでも設定を切り替えることができます。
|
||
|
||
### ゲームの入力バインディングをどこで設定したらよいですか?
|
||
|
||
Unity では、プロジェクトの Input Manager 設定を使用してデフォルト バインディングをセットアップしています。UE4 も同じようにできます。Project Settings (プロジェクト設定) を開いて、Input カテゴリを選択します。ここでは、様々なボタン (アクション) やアナログ コントロール (軸) を追加することができます。各コントロールに名前とデフォルト バインディングを与えます。入力イベントがトリガーされるとゲームのポーンをコールバックします。詳細については、[インプット ドキュメントのページ](Gameplay/Input) をご覧ください。
|
||
|
||
### プロジェクトの開始シーンの変更方法は?
|
||
|
||
プロジェクトの設定タブからプロジェクトのスタートアップ マップを変更できます。メイン メニューから Edit/Project Settings->Maps & Modes の順に選択してスタートアップ マップを変更します。
|
||
|
||
### ゲームを実行する方法は?
|
||
|
||
ゲームを実行する一番簡単な方法は、メイン エディタのツールバーで [Play] ボタンをクリックすることです。これで、エディタのプロセス内でゲームを実行します。スタンドアロンのアプリケーションとして実行したい場合は、[Play] ボタンの隣にあるドロップダウンの矢印をクリックして、「Standalone Game」を選択します。最後に、モバイル デバイスまたはウェブ ブラウザで実行したい場合、ツールバーの [Launch] ボタンを使用します (プラットフォームで事前に必要なものをインストール後)。
|
||
|
||
### 単位は?
|
||
|
||
Unity では、計測の基本単位は 1 m です。UE4 では、計測の基本単位は 1 cm です。
|
||
|
||
そのため、Unity で何かを 1 単位 (m) 動かすと、UE4 で何かを 100 単位(cm) 動かすことに相当します。
|
||
|
||
Unity で何かを 2 フィート動かすと 0.61 単位 (メーター) になり、UE4 では 61 単位 (cm) になります。
|
||
|
||
### 座標系はどのようになっていますか?どちらの方向が上?
|
||
|
||
Unity と UE4 は両方とも左手座標系ですが、軸は入れ替わっています。UE4では+ X 軸は「前」で、+ Y 軸は「右」、+ Z 軸は「上」になっています。これは変更できないため慣れていただくしかありません。
|
||
|
||
### どうしたらゲームからログの出力が見ることができますか?
|
||
|
||
UE4 エディタでは、 "Window -> Developer Tools" メニューから Output Log を開くことができます。ゲームを "-log" コマンドライン パラメータで実行し、ゲームの横に専用ログ ウィンドウを呼び出すことができます。これはとても便利です。
|
||
|
||
### ログ出力といえば、Debug.Log はどこにあるのでしょう?
|
||
|
||
UE4 のロギングは高度なカスタマイズが可能です。メッセージのログをとる方法については、[ここ](https://wiki.unrealengine.com/Logs,_Printing_Messages_To_Yourself_During_Runtime) をご覧ください。
|
||
|
||
### 例外のスローはどのように行うのでしょうか?
|
||
|
||
Unity では、何かがうまくいかないときに例外をスローしていました。UE4 では、例外処理を使用しません。代わりに、'check()' 関数を使用してクリティカルなアサーション エラーをトリガーします。エラー メッセージを渡すことができます。エラーを報告したいが、プログラムを停止したくない場合は、代わりに 'ensure()' を使用します。これで、完全なコールスタックをログに出力しますが、プログラムは実行され続けます。デバッガーをアタッチすると、両方の関数はデバッガでブレークします。
|
||
|
||
###.NET フレームワークはどこですか?
|
||
|
||
Unity とは異なり、UE4 では .NET フレームワークを使用しません。UE4 には独自のコンテナ クラスとライブラリのセットがあります。一般的なコンテナの比較です。
|
||
|
||
|
||
| .Net Framework | UE4 |
|
||
| --- | --- |
|
||
| String | [FString](https://docs.unrealengine.com/latest/INT/API/API/Runtime/Core/Containers/FString), [FText](https://docs.unrealengine.com/latest/INT/API/API/Runtime/Core/Internationalization/FText) |
|
||
| List | [TArray](https://docs.unrealengine.com/latest/INT/API/API/Runtime/Core/Containers/TArray) |
|
||
| Dictionary | [TMap](https://docs.unrealengine.com/latest/INT/API/API/Runtime/Core/Containers/TMap) |
|
||
| HashSet | [TSet](https://docs.unrealengine.com/latest/INT/API/API/Runtime/Core/Containers/TSet) |
|
||
|
||
|
||
|
||
その他の UE4 コンテナの詳しい情報については [ここ](https://docs.unrealengine.com/latest/INT/API/Runtime/Core/Containers/index.html) をご覧ください。
|
||
|
||
### アンリアル エンジンではコード変更を自動的にリロードしますか?
|
||
|
||
はい、します。コードを記述中にエディタを開いたままにすることができます。コード編集後に Visual Studio からコンパイルを開始すると、エディタは変更を自動的に「ホット リロード」します。エディタのメイン ツールバーで **コンパイル** ボタンをクリックすることもできます。これは、Visual Studio のデバッガをアタッチした場合に役立ちます。
|
||
|
||
## ここから先のこと
|
||
|
||
ガイドをお読みいただきありがとうございます。本ガイドは、アンリアル コミュニティ向けに多くのデベロッパーの支援により作成されたものです。フィードバックや訂正があればご指摘いただければ幸いです。UE4 への移行で何が最も役立つかを学びながらこのガイドの改善を続けるつもりです。
|
||
|
||
これ以外にも、以下のように多くの UE4 学習リソースをご用意しております。
|
||
|
||
* ドキュメント
|
||
|
||
* まずはここから - [まずはここから](GettingStarted)
|
||
|
||
* チュートリアル ビデオ - [ビデオ](https://wiki.unrealengine.com/Videos)
|
||
|
||
* API - [API](https://docs.unrealengine.com/latest/INT/API/index.html)
|
||
|
||
* AnswerHub - [https://answers.unrealengine.com](https://answers.unrealengine.com)
|
||
|
||
* フォーラム - [https://forums.unrealengine.com](https://forums.unrealengine.com)
|
||
|
||
* Wiki - [https://wiki.unrealengine.com](https://wiki.unrealengine.com)
|
||
|
||
* Wiki ページの[UE4 coming from Unity](https://wiki.unrealengine.com/Unity3D_Developer%27s_Guide_to_Unreal_Engine_4)
|
||
|
||
|
||
|
||
|