Unreal Engine 4と
Unreal C++での
プログラミング環境について
Event for Diverse Game Engineers
by alwei
自己紹介
HN : alwei (アルウェイ)
関西アンリアル勢
Twitterよくやっています → @aizen76
元々はゲームプログラマーを8年ほどやっていました。
今は独立してフリーになってゲーム制作に関連する
お仕事を受けるようになり、ゲーム作りの何でも屋。
ゲームをやるのも作るのも大好き。
趣味でお絵描きやモデリングもやりながらゲーム制作。
Unreal Engine 4について
最近無料化したゲームエンジン。
3Dゲームから2Dゲームまで割りと何でも作れる。
最新作のドラクエ11のPS4版がUE4採用という事で話題に。
なんとドラマ版デスノートのリュークのCGもUE4だとか。
その他日本のゲームでも沢山採用されており、
業界内外から注目を集めている。
Epic Games Launcherより
UE4でのロジック制作環境
先に断わっておくと、UE4ではC++コードを書くよりも
ブループリントと呼ばれるビジュアルスクリプトシステムで
ゲームは完全に制作可能です。
特にこだわりがなければ、
C++よりもブループリントを
使う事をおすすめします。
ブループリント超強力なんで!!
じゃあなんでC++を使うの?
なんでC++を使うの?
『パフォーマンスがもっと欲しい』
『エンジンやエディターを拡張したい』
『外部ライブラリーやSDKを使いたい』
『独自デバイスを繋ぎたい』
『C++の勉強に』
等々…ブループリントだけでは不可能なあらゆる事が
可能となるので、用法要領を守ってお使いください
早速ですが…
Unreal C++は素晴しい!
Unreal C++って何?
C++を初心者でも使いやすくし、
更に沢山の独自拡張を施す事によって
Unreal Editorとの親和性を高めている。
その独自拡張故に、既存のC++にはないメリットがある。
C#やJavaやJava Scriptの特徴も取り込んでおり、
そういった言語を学んだプログラマーなら入りやすい。
ビルドアーキテクチャー
ビルドシステムについて
Unreal Build Toolがプロジェクト全体を解析。
独自拡張されたC++部分のメタ情報も作りだす。
Mono C#はクロスプラットフォームで動作する、
Unreal C++のモジュールシステムやライブラリーの
管理やリンクを行ない、プロジェクトデータを生成する。
最終的な情報をVisualStudioやXcodeに
渡す事によってビルドを完了させる。
実はWindows、MacだけではなくLinuxでも動作する。
Unreal C++の特徴
• 比較的モダンC++
• エンジン全体で統一されたコーディングルール
• C++11ベースでC#にも近いスタンダードライブラリー
• 徹底的に自動化されたコード生成環境
• 完全なメモリー管理とガベージコレクション搭載
• メタ情報による独自リフレクションシステム
• ブループリントとの完全な連携
• 実行中にC++コードを書き換えるホットリロード
比較的モダンC++
近年のC++の特徴は大体取り込んでいる。
ライブラリーのコンテナはRange based forに対応。
同様にコンテナはムーブセマンティクスにも対応しており、
一時オブジェクトのコピーは発生しない。
コンテナのアルゴリズムには無名関数による、
ラムダ式での記述も可能。
autoキーワードや強い型付けのenumなどのC++11で
追加された機能の使用を推奨している。
比較的モダンC++
ただし全てのコンパイラーが対応していない機能には
慎重になっており全てがモダンというわけではない。
コンパイラーの対応により少しずつ機能が拡充されている。
しかしあくまでもC++を簡単に扱えるようにするために、
C++の難解部分の使用は避けられている。
コーディングルール
コーディングルール
https://docs.unrealengine.com/latest/JPN/Programming
/Development/CodingStandard/index.html
エンジン全体で統一されたコーディングルールがあるため、
プロジェクトでもこれを採用すれば混乱が少ない。
コーディングルール自体はC#の標準にかなり近い。
読み易さ重視により、クセのない書き方になっている。
変な文化のルールに従うよりもこれを採用した方が良い。
コーディングルール
コードの宗教戦争はやめよう\(^o^)/
スタンダードライブラリー
C++のスタンダードライブラリーは使いません。
Unreal C++ではゲーム用に特化したライブラリーが用意
されており、マルチプラットフォームで統一された動作、
メモリー管理、独自拡張が提供されます。
ベースはC++11になっており、その他の言語の特徴を
ライブラリーに沢山取り入れている。
コンテナ
コンテナ
C++標準よりも圧倒的に数が多い。
std::vector → TArray
std::unordered_set → TSet
std::unordered_map → TMap
どれもベースはあるが、C#のようなメソッドが追加されて
更に使い勝手が良くなっている。
もちろんラムダ式やムーブセマンティクスにも対応。
イテレーターはRange based for形式で使用可能。
文字列
■FString
std::stringがベースであるものの、ほぼ別物。
使い勝手はC#のString型そのものに近い。
SplitやTrimなどの分割や豊富な文字列検索機能あり。
■FText
文字列を実際に表示するためのシステム。
完全なマルチ言語対応になっていて、UE4の言語切り替えで
別の言語表示にネイティブ対応出来るようになっている。
文字列
■FName
データ上、完全に静的な扱いとなる文字列。
FStringやFTextと違い、ランタイム変更が出来ないので、
キーによる参照が圧倒的に速い。
アセットの名前などゲーム中に変わらない文字列に使う。
UE4の文字列は最初から多言語対応を前提としており、
エンコードシステムに従えばあらゆる言語に対応可能。
ネットワークを通じてのシリアライズ、デシリアライズにも
しっかりと対応している。エンディアン変換もOK。
デリゲート
C#にあるデリゲートのような機能を持ちながら、
std::functionのように完全に型安全な関数コールが可能。
MyDelegate.BindUObject(&MyClass::MyFunction);
MyDelegate.Execute(true, 20);
いくつでも関数を追加・削除、更に一度でブロードキャスト
呼び出し出来るマルチキャストデリゲートや、
シリアライズ可能なダイナミックデリゲートという
特殊なデリゲートもある。
自動化されたコード生成環境
プロジェクトファイルにコードを追加する際に、
IDEから直接追加せずにUnreal Editorが自動で行なう。
また生成されたコードの配置やテンプレートコードも
同時に作成されるため、追加も楽でミスも少ない。
.cppと.hを個別に作成する必要もなく、
ヘッダーのインクルードも同時に行なわれる。
自動化されたコード生成環境
手間のかかるコード生成はエディターのGUIから
クラスウィザードでクラス名を入力するだけでOK!
完全なメモリー管理とGC搭載
C++だけど、ガベージコレクションあり。
全てのクラスのベースクラスである、
UnrealObject(UObject)を継承したクラスであれば、
自動的にUE4のガベージコレクターへ登録。
MyGCType* DoomedObject =NewObject<MyGCType>();
これで後は適切なタイミングで破棄してくれる。
GCの最適化
GCの制御も可能。
GCの呼び出し間隔や
強制的なGC呼び出しも可能。
更に並列化GCや、
一定サイズパーマネントの
オブジェクトプール化も可能。
メモリーの可視化
当然全てのメモリーは
トラッキングされているので
使用状況はいつでも確認可能!
使用状況だけでなく、
GCやオブジェクトプール
情報やメモリーによる負荷を
知る事が出来る。
より詳細は更に各々の
プロファイラーで確認可能。
スマートポインター
UObjectでないものはGC対象にならないので、
そういう場合にはスマートポインターを使う。
TSharedPtr(共有ポインター)
TSharedRef(参照型の共有ポインター)
TWeakPtr(弱参照ポインター)
基本はBoostやSTLにあるものと同様だが、
ゲームで使用する前提の設計になっている。
標準スマートポインターとの違い
• コンソール、ハードウェアやコンパイラーを意識した実装
• BoostやSTLよりも高速に動作
• デフォルトはスレッドセーフではない
• スレッドセーフ版が存在(TThreadSafeSharedPtr等)
• スレッドセーフ版はロック・フリー採用
• コピー時にメモリー割り当てを行なわない
基本的にパフォーマンスを優先。
無駄なメモリー確保をしない。
コンソールでの実用を考えて例外機構を使用しない。
メタ情報によるリフレクション
C++にはリフレクション機能がない。
RTTI(実行時型情報)はあるが、無駄が多く機能が弱い。
Unreal Build Toolの中にUnreal Header Toolというものが
あり、コンパイラー実行前にヘッダーのメタ情報を解析する。
このメタ情報から自動的にリフレクション用のヘッダーを
生成する事が出来る。このヘッダーは自動生成でかつ
クラス追加時に自動的にインクルードされるので、
何も意識しなくても使用する事が可能になっている。
メタ情報について
メタ情報について
通常のC++には存在しない書き方になっている。
クラスや変数や関数、構造体につける事が可能。
• UCLASS
• UPROPERTY
• UFUNCTION
• USTRUCT
もし記法にミスがあるとUnreal Header Toolが
エラーを表示してくれるようになっている。
リフレクション
// イテレーターを使用して、クラスの名前を取得。
for (TObjectIterator<UObject> It; It; ++It)
{
UObject* CurrentObject = *It;
UE_LOG(LogTemp, Log, TEXT("Found UObject named: %s"),
*CurrentObject.GetName());
}
更にメタ情報について
メタ情報はリフレクションだけのためのものではない。
クラスや変数、関数に様々な機能を追加する事が出来る。
ブループリントへの情報、カテゴリー分け、
ローカライズ変数、セーブデータ変数、ネットワーク変数、
サーバー関数、クライアント関数などなど…
Unreal C++にとってメタ情報は
なくてはならないコア機能となっている。
ブループリントとの完全な連携
メタ情報を使いこなす事により、
ビジュアルスクリプトシステムと完全な連携が可能。
// プレイヤーのライフを宣言
UPROPERTY(BlueprintReadWrite, Category=“Player”)
float Life;
// プレイヤーのライフを表示
UFUNCTION(BlueprintCallable, Category=“Player")
void DisplayLife();
ブループリントへ公開
C++に書いた内容がブループリント上へと追加されています。
ホットリロード
エディター、ゲーム実行中にC++コードを
書き換える事が可能です。
何言ってんの?
いやいや、冗談でしょ?
ホットリロード
エディター、ゲーム実行中にC++コードを
書き換える事が可能です。
Unreal C++は完全なモジュールシステムを
採用しているため、実行時に書き換えた部分のみ、
DLLをリロードする事でC++コードを読み直す。
C++を使っている人には一番衝撃を受ける機能のひとつ。
ホットリロード実演
Unreal C++は素晴らしい!
以上でUnreal C++の基礎部分だけですが、
様々な事が判ったと思います。
ブループリントの凄さに隠れがちですが、
Unreal C++はC++の煩わしさを軽減し、
C++をストレスフリーに使える機能が沢山あります。
ただし、C++を無理して使う必要はありません。
ブループリントだけでも十分にゲームを作れる
ということは忘れないでください。
Unreal Fest 2015 横浜
エピック・ゲームズ・ジャパン公式の
Unreal Engineセミナーイベント!
参加募集人数なんと1000人!
10/18(日)9:30~19:00
こちらでも登壇しますのでよろしくネ!

UE4とUnrealC++について