58.1K Views
May 12, 22
スライド概要
Event for Diverse Game Engineersというイベントで喋った時のスライドです。
Unreal Engine 4のC++環境についての解説です。
Event for Diverse Game Engineers Unreal Engine 4と Unreal C++での プログラミング環境について 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 こちらでも登壇しますのでよろしくネ!