VR
oga at 12:56
Oculus Go に続いて上位機種 Oculus Quest が登場しました。両手のモーションコントローラ含めてポジショントラッキングに対応しており、スタンドアロンながら 6.6DoF のフルスペック VR になっています。

Oculus Quest にも Oculus TV が入っており、以前作成した TVLauncherGo がそのまま使えるようです。Oculus Go と同じように Oculus TV 上で Android アプリが動きました。

・設定アイコンから Bluetooth Keyboard の接続
・同じく設定から物理キーボードのキーレイアウト変更
・UserLAnd を使って Linux をインストール
・VNC アプリの起動 (制限あり)

などなど一通りうまくいっています。UserLAnd が動けば、開発環境や日本語入力環境の構築ができます。

つまり Oculus Quest と Bluetooth Keyboard を持ち歩けばどこでも大画面で作業に没頭できるようになるわけです。

Oculus Quest + UserLAnd + Ubuntu + bVNC

ちなみに開発環境には Termux も併用しています。Termux 自体は TVLauncherGo がなくても動きます。(併用する理由はこちら)


● Oculus Quest の速度

Oculus Go よりも性能が上がってだいぶ快適になりました。下記の表は Termux 上でのコンパイル速度の比較です。Quest は Go よりも 2.6 倍速くなっています。

VR あり VR利用 SoC RAM Thread Time
Daydream + Pixel 3 あり Snapdragon 845 4GB 8 72
Oculus Quest あり Snapdragon 835 4GB 8 105
Oculus Go あり Snapdragon 821 3GB 4 275
Daydream + ZenFone AR あり Snapdragon 821 8GB 4 349
VR なし VR利用 SoC RAM Thread Time
Pixel 3 無し Snapdragon 845 4GB 8 32
Essential Phone 無し Snapdragon 835 4GB 8 38
ZenFone 3 Max ZC553KL 無し Snapdragon 430 3GB 8 100
ZenFone AR ZS571KL 無し Snapdragon 821 8GB 4 111
Nexus 5X 無し Snapdragon 808 2GB 6 135

・Time の単位は秒。値が小さい方が高速。

当然ながら VR を使わない状態だともっと高速です。同じ SoC を搭載した機種同士で比べると、VR 空間上でのコンパイルは通常の状態より 2.5 倍前後遅くなっています。それだけ VR の描画は負荷が高いわけです。

Quest の結果は VR 無しの ZenFone AR (Snapdragon 821) や ZenFone 3 Max (Snapdragon 430) とほぼ同じくらいになっています。VR 上で素の Snapdragon 821 や Snapdragon 430 が動いていると思えば速度のイメージが掴めるのではないでしょうか。

比較用に Daydream も試しましたが、Snapdragon 845 の Pixel 3 は速いものの画面解像度が低く実用には厳しいものがありました。XL ならちょうど良いのかもしれません。Zenfone AR はビルド中、発熱のためか処理落ちが多く不安定でした。やはり専用機である Oculus Go や Quest は解像度が高く画面端の歪みもなく安定しています。


●持ち歩きやすさ

可搬性に関しては Go の方が上です。性能が上がりサイズと重量が若干増えたのもありますが、バンドがしっかりした作りになったため Go のように折り畳めなくなっています。また場所が変わると毎回ガーディアン設定が出てくるので、使うまでにひと手間かかります。

Oculus Go と Oculus Quest


●ポジショントラッキング

ポジショントラッキングのおかげで VR 内での見え方はかなり自然になりました。スクリーンに近づいたり離れたりできるので、文字が小さくて見えにくい場合も近寄れば読むことができます。ただしガーディアン範囲を抜けると外部カメラ映像に切り替わってしまうので、大きく動く場合はルームスケールの範囲設定が必要。



●環境設定など

Go とはコントローラが違いますが使うボタンは限られています。Oculus TV で前の画面に戻るには (B) ボタンを使います。

Oculus TV で前の画面に戻る操作
・Oculus Go : メニューボタン
・Oculus Quest : 右コントローラの (B) ボタン


(1) TVLauncherGo の apk を install

(2) Oculus TV → TVLauncherGo → 設定アイコン → Bluetooth
 ・ Bluetooth キーボードを接続
 ・ 必要に応じてレイアウト選択
  ・ 設定の言語→キーボードレイアウト
  ・ (「106/109106/109ハードウェアキーボード配列変更 (+親指Ctrl) [日本語配列]」が使えます。

(3) UserLAnd の apk を install

(3) Oculus TV → TVLauncherGo → UserLAnd
 ・Linux install (SSH を選択)


下記の記事も参考にしてください。
Oculus Go を文章書き&開発マシンにする
Oculus Go で一般 Android アプリを起動できるランチャーを作ってみた



● VNC を使う場合

UserLAnd が bVNC Free 以外の client にも対応したため手順が若干変わりました。Real VNC Viewer を使う場合でも UserLAnd が直接呼び出してしまうため、一旦停止させてから Oculus TV 経由で起動する必要があります。そのかわり複数の VNC client を入れることで起動をキャンセルできます。

以下は「環境設定など」の続きです。


(1) Real VNC Viewer の apk を install

(2) Oculus TV → TVLauncherGo → UserLAnd
 ・ Linux Distribution 名長押しで VNC に変更

(3) Linux を起動すると画面真っ黒でロード待ちになるので、右コントローラの Oculus Button で戻る
 ・Real VNC Viewer は大丈夫ですが、bVNC だとここで戻れないので再起動になります。

(4) 右コントローラの (B) ボタンで TVLauncerGo に戻り強制停止する
 ・VNC Viewer アイコン長押しで「アプリ情報」の画面を開く (設定→アプリ→VNC Viewer でも構わない)
 ・VNC Viewer アプリを強制停止する (起動した状態を一旦クリアするため)

(5) TVLauncerGo に戻る

(6) あらためて VNC Viewer を起動し、下記の設定で接続する
  ・ HOST: 127.0.0.1
  ・ PORT: 5951

(7) VNC 接続時にパスワードを聞かれるので、UserLAnd の Linux アカウント作成時に設定した VNC Password を入れる


最初は画面が Native 解像度になっているので ~/.vncrc を書き換えて調節してください。1280x720 推奨。

UserLAnd の日本語環境設定についてはこちらを参考にしてください。

なお Real VNC Viewer は比較的安全に起動できますが、モーションコントローラでのマウス操作には難があります。ウィンドウなどドラッグ移動できないのと、ちょっとしたブレでタスクバーのメニューが開かないなど制限があります。少々手間がかかりますが bVNC を使う方法があります。



● VNC を使う場合 (bVNC)

UserLAnd からの呼び出しをキャンセルするために、Real VNC Viewer と bVNC の両方を install しておく必要があります。必ず Bluetooth Keyboard を接続しておいてください。


(1) Real VNC Viewer の apk を install

(2) bVNC の apk を install

(3) Oculus TV → TVLauncherGo → UserLAnd
 ・ Linux Distribution 名長押しで VNC に変更

(4) Linux を起動すると VNC client 選択画面になるので、Bluetooth Keyboard の [ESC] を押してキャンセル

(5) 右コントローラの (B) ボタンで TVLauncerGo に戻る

(6) TVLauncerGo から bVNC を起動

(7) 下記の設定で接続する。右上の [CONNECT] を押す
  ・ HOST: 127.0.0.1
  ・ PORT: 5951
  ・ Linux アカウント作成時に入力したユーザー名とパスワード

(8) つながったら bVNC の設定メニューから 「Input Mode」 → 「Direct, Hold Pan」 を選択する


これでモーションコントローラだけでウィンドウ操作もできるようになります。タスクバーのメニューも簡単に開きます。

Oculus TV を経由せずに UserLAnd が直接 bVNC を起動してしまうと操作できなくなるので注意してください。



関連ページ
Android の上の開発環境
HMD VR / AR Device spec 一覧

関連エントリ
Android UserLAnd の更新と VNC 画面設定
UserLAnd : Android 9.0 で Ctrl + SPACE を使えるようにする
Android Termux で日本語入力を行う / UserLAnd との併用
Android 9.0 と Bluetooth Keyboard による日本語入力
Android/Oculus Go/Daydream の画面をミラーリングするツールを作ってみた
Oculus Go で一般 Android アプリを起動できるランチャーを作ってみた
Oculus Go を文章書き&開発マシンにする
UserLAnd とブラウザ
Android 上の開発環境と UserLAnd
OS の中の Linux (WSL/Chrome OS/Android UserLAnd)
ARM CPU 上の開発環境とコンパイル時間の比較 (2) Pixel 3/UserLAnd
Oculus Go は VR ができる新しい携帯ゲーム機


UserLAnd を使うと Android 上に簡単に Linux 環境を構築することができます。開発環境としてはすでに termux がありますが、UserLAnd の場合動作可能なソフトウエアが多いのが魅力です。日本語入力環境も構築できるので、termux を補う意味でも併用がおすすめ。

前回までの記事はこちら

結構こまめに更新されているので、修正された部分などいくつか。


●画面サイズの自動認識

以前は VNC を選択すると 1024x768 の固定サイズになっていました。大半のスマートフォンはアスペクト比が異なるので、画面いっぱいに広げるには自分で設定ファイルに解像度を書き込んでおく必要があります。

新しい UserLAnd では自動的にスマートフォンの画面に合わせたサイズが選ばれるようになっています。設定をいじらなくても全画面です。

ただしハイエンド機種はピクセル密度が高いので、そのままだと文字が読めないほどウィンドウが小さくなってしまう場合があります。(5.5inch で 2560x1440 dot など) 必要に応じて .vncrc を修正してください。


●VNC 画面サイズの設定方法

従来は Linux Distribution 毎に設定ファイルが異なっていました。例えば Debian は ~/.vncrc で行い、Ubuntu は ~/.vnc/tightvncserver.conf、Arch Linux は ~/.vnc/config とばらばらです。

新しい UserLAnd では ~/.vncrc に統一されています。proot 外のスクリプトによって VNC Server 起動時に $HOME/.vncrc を読み取って起動時のコマンドオプションに指定しているようです。Debian は問題ありませんが、Ubuntu や Arch の場合以前の設定が無効化されているので注意。


●Desktop 環境のインストール

UserLAnd のアプリケーションメニューに Desktop が追加されたので、コマンドを打たなくてもデスクトップ環境を install できるようになっています。Lxde, Xfce の選択ができます。ただしインストールされるのは Debian になります。

UserLAnd Xfce

以前は VNC を選択してもデフォルトの twm + xterm のみで、Desktop 環境は自分でインストールする必要がありました。


●その他細かいこと

Alpine Linux が追加されているので Alpine, Arch, Debian, Kali, Ubuntu の 5種類から選択できるようになっています。

Filesystem のバックアップが可能になっています。Filesystem タブから個別に Export, Import できるようです。



関連エントリ
UserLAnd : Android 9.0 で Ctrl + SPACE を使えるようにする
Android Termux で日本語入力を行う / UserLAnd との併用
Android 9.0 と Bluetooth Keyboard による日本語入力
Android で動く Linux 環境 UserLAnd が XServer XSDL に対応
Oculus Go を文章書き&開発マシンにする
UserLAnd とブラウザ
Android 上の開発環境と UserLAnd
OS の中の Linux (WSL/Chrome OS/Android UserLAnd)
ARM CPU 上の開発環境とコンパイル時間の比較 (2) Pixel 3/UserLAnd


UE4
oga at 20:26
UE4 のビルドツール UnrealBuildTool はビルドファイルの定義に *.Target.cs や *.Build.cs を使います。それとは別に、デフォルトパラメータを定義できる BuildConfiguration.xml があります。

UE4 Programming Guide / BuildTools / UnrealBuildTool / Build Configuration

例えば次の内容で BuildConfiguration.xml を作り、Documents のフォルダ "Unreal Engine\UnrealBuildTool" に入れておくと UnityBuild を無効化することができます。

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
        <BuildConfiguration>
                <bUseUnityBuild>false</bUseUnityBuild>
        </BuildConfiguration>
</Configuration>

※ UnityBuild を off にするとビルドが極端に遅くなるのでお勧めしません。

BuildConfiguration.xml のチェックが行われている場所は以下の 4 つです。

(1) Engine\Programs\NotForLicensees\UnrealBuildTool\BuildConfiguration.xml
(2) Engine\Saved\UnrealBuildTool\BuildConfiguration.xml
(3) C:\Users\<USERNAME>\AppData\Roaming\Unreal Engine\UnrealBuildTool\BuildConfiguration.xml
(4) C:\Users\<USERNAME>\Documents\Unreal Engine\UnrealBuildTool\BuildConfiguration.xml

この順番で読み込まれるため、下の方が優先順位が高くなります。

(3), (4) はすべてのエンジンに対して有効になります。UE4 のバージョンによって設定項目に若干違いがあるので、複数のエンジンを併用している場合は注意が必要です。エンジンによってエラーが出る場合は (2) のようにエンジン毎のフォルダに入れておいた方が良いかもしれません。

たとえば ProcessorCountMultiplier は UE4 4.20 までは BuildConfiguration に含まれていました。4.21 では無くなっており、代わりに Executor 毎の個別パラメータを使うようになっています。

UE4 4.20 の場合

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
        <BuildConfiguration>
                <ProcessorCountMultiplier>2.0</ProcessorCountMultiplier>
        </BuildConfiguration>
</Configuration>



UE4 4.21 の場合

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
        <LocalExecutor>
                <ProcessorCountMultiplier>2.0</ProcessorCountMultiplier>
        </LocalExecutor>
        <ParallelExecutor>
                <ProcessorCountMultiplier>1.0</ProcessorCountMultiplier>
        </ParallelExecutor>
</Configuration>

ParallelExecutor は 4.21 で新しく追加されたものです。以前の LocalExecutor も残っていますが、分散ビルドを使わない場合 4.21 以降はデフォルトが ParallelExecutor になります。

LocalExecutor の場合、4 core 8 thread の CPU ではデフォルトでビルドに 4 thread 使います。ProcessorCountMultiplier を 2.0 にすると 8 thread 全部使うようになります。8 core 16 thread の CPU ではなぜかデフォルトで 12 thread、ProcessorCountMultiplier を 2.0 にすると 16 thread になります。計算が合わないように見えるのは、5 core 以上で計算式が変わるからです。

// UBT LocalExecutor の計算式
if( ProcessorCountMultiplier == 1.0 ){
   if( Core数 > 4 ){
       ビルドに使う thread 数 = ( Core数 + Thread数 ) / 2;
   }else{
       ビルドに使う thread 数 = Core数;
   }
}else{
   ビルドに使う thread 数 = Core数 * ProcessorCountMultiplier;
}

4.21 から追加された ParallelExecutor では特に ProcessorCountMultiplier を設定しなくても、最初からハードウエアと一致する 8 thread や 16 thread でビルドが行われています。まとめると下記の通り。


Executor LocalExecutor ParallelExecutor
Multiplier 1.0 2.0 1.0 2.0
Skylake i7-6700K ( 4C8T ) 4 8 8 16
CoffeeLake i7-8700K ( 6C12T ) 9 12 12 24
Ryzen 7 1800X ( 8C16T ) 12 16 16 32

つまり以前の LocalExecutor の場合、ProcessorCountMultiplier = 2.0 は効率を上げるために有効でしたが、ParallelExecutor では本来の倍のスレッドが走ってしまいます。古い設定を継承するとスレッド数が過剰になるため BuildConfiguration から削除されたのかもしれません。ちなみに ParallelExecutor は下記の設定で無効化できます。

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
        <BuildConfiguration>
                <bAllowParallelExecutor>false</bAllowParallelExecutor>
        </BuildConfiguration>
</Configuration>

このように UnrealBuildTool には様々な設定があります。オプションの種類は下記のファイルを見るとわかります。

Engine\Saved\UnrealBuildTool\BuildConfiguration.Schema.xsd

このファイルを見ると UE4 4.22 からは cpp のオプションが増えている事がわかります。下記のような設定もできるようになりました。

<?xml version="1.0" encoding="utf-8"?>
<Configuration xmlns="https://www.unrealengine.com/BuildConfiguration">
        <BuildConfiguration>
                <CppStandard>Cpp14</CppStandard>
        </BuildConfiguration>
</Configuration>


関連エントリ
UE4 UnrealBuildTool VisualStudio の選択を行う
UE4 UnrealBuildTool *.Build.cs のコードを共有する


UE4
oga at 19:35
UE4 で C++ プロジェクトを作ると VisualStudio 用のプロジェクトファイル *.vcxproj や *.sln も自動的に作られます。ただしこれらのファイルは UE4 のビルドシステムにとっては必ずしも必要ではなく、IDE を使うための中間ファイルとみなされています。そのため IDE プロジェクトファイルは Git や Perforce には登録されず、必要になったタイミングで作り直します。

VisualStudio プロジェクトファイルを作るには *.uproject ファイルの関連付けを利用するのが最も簡単です。*.uproject ファイルの上で右クリックして "Generate Visual Studio Project files" を選択します。

このとき呼ばれているツールは UnrealVersionSelector.exe です。内部で UnrealBuildTool を呼び出しているのですが、UnrealVersionSelector 経由だとあまり細かいオプション指定ができないようです。

オプション指定を行う場合は、直接 UnrealBuildTool を呼び出すか、またはソースコード版 Engine の GeneratedProjectFiles.bat を使うことができます。


●任意の VisualStudio のバージョンを指定して Project File を作る

UnrealBuildTool や GeneratedProjectFiles.bat を使うと、使用する VisualStudio のバージョンを指定することができます。*.uproject への関連付けも不要ですし、複数のバージョンの VisualStudio をインストールしている場合に便利です。

例えば UE4 4.21 で VisualStudio 2015 を使う場合下記のように "-2015" オプションを指定します。

set ENGINE_PATH=c:\Program Files\Epic Games\UE_4.21

"%ENGINE_PATH%\Engine\Binaries\DotNET\UnrealBuildTool.exe" -projectfiles -project=c:/ue/MyProject421/MyProject421.uproject -game -engine -progress -2015

*.uproject ファイルはフルパスで指定する必要があるので注意。

GitHub のソースコード版を使っている場合は GeneratedProjectFiles.bat を使って同じことができます。

set ENGINE_PATH=c:\ue\4.21.0

%ENGINE_PATH%\GeneratedProjectFiles.bat -project=c:/ue/MyProject421/MyProject421.uproject -game -engine -progress -2015

同様に -2017 や -2019 (4.22 以降) もあります。↓ 4.22 で 2019 を使う場合の例。

c:\ue\4.22.0\Engine\GeneratedProjectFiles.bat -project=c:/ue/MyProject422/MyProject422.uproject -game -engine -progress -2019

ソースコード版エンジンそのものをビルドする場合は GeneratedProjectFiles.bat に -2017 や -2019 などのオプションをつけるだけで OK です。

c:\ue\4.22.0\GeneratedProjectFiles.bat -2019


●プロジェクトファイルの Platform 数を制限する

プロジェクトファイルを作るときに、-platforms オプションを与えておくと不要な Platform を除外してくれます。例えば Win64 と Android だけ含めたい場合は "-platforms=Win64+Android" になります。プロジェクトファイルが小さくなるので、VisualStudio での読み込みが若干速くなります。

set ENGINE_PATH=c:\ue\4.21.0

%ENGINE_PATH%\Engine\Binaries\DotNET\UnrealBuildTool.exe -projectfiles -project=c:/ue/MyProject421/MyProject421.uproject -game -engine -progress -2015 -platforms=Win64


●ビルド時に直接コンパイラのバージョンを指定する

UE4 のビルドは UnrealBuildTool が行います。IDE も UnrealBuildTool を呼び出しているだけなので、直接ビルドすることもできます。この場合も -2015 や -2017 等のオプション指定ができます。

set ENGINE_PATH=c:\ue\4.21.0

%ENGINE_PATH%\Engine\Build\BatchFiles\Build.bat MyProject421Editor Win64 Development -project=c:/ue/MyProject421/MyProject421.uproject -2015

最初の引数 "MyProject421Editor" は、ビルド対象の *.Target.cs を意味しています。"MyProject421Editor" は MyProject421Editor.Target.cs を選択します。Editor なしでビルドしたい場合は MyProject421 です。

4.21 と 4.22 では若干引数が変わっているので、直接 UnrealBuildTool.exe を呼び出すよりは Build.bat や Rebuild.bat を使った方がおそらく安全でしょう。

どのようなコマンドライン引数でビルドが行われているのか VisualStudio のプロパティからも確認できるので、うまくビルドできない場合は確認してみることをおすすめします。


関連エントリ
UE4 UnrealBuildTool *.Build.cs のコードを共有する


UE4
oga at 19:18
UE4 は C# で書かれた独自のビルドシステム UnrealBuildTool を使用しています。Makefile に相当するのが Module 毎に用意する *.Build.cs ファイルです。

例えば GameProject/Source/GameModule をビルドする場合下記のようなファイルを作ります。

// GameProject/Source/GameModule/GameModule.Build.cs
using  UnrealBuildTool;

namespace UnrealBuildTool.Rules
{
    public class GameModule : ModuleRules {
        public GameModule( ReadOnlyTargetRules Target ) : base( Target )
        {
        }
    }
}

この中で依存モジュールの宣言や、外部ライブラリの path 追加などさまざまな設定を行うことができます。

*.Build.cs の他に Project 全体の設定を記述する *.Target.cs もあります。

*.Build.cs Module 毎のビルド設定
*.Target.cs Project 全体のビルド設定

Target.cs はあくまで Project 単位に用意するため Plugin にはありません。また Build 対象に応じて Target.cs が変わるため複数存在します。

~.Target.cs Game
~Editor.Target.cs Editor
~Server.Target.cs Server
~Client.Target.cs Client


●他の Module を参照する場合

UE4 内部の Module 同士の依存関係は Module 名で管理されています。そのため Module については個別に Include path を与えたり Link するライブラリを指定する必要がありません。

例えば依存ファイルとして下記のような宣言を行えば、それぞれの Module への include も Link する Lib も自動で管理してくれます。

PublicDependencyModuleNames.AddRange( new string[] {
        "Core",
        "CoreUObject",
        "Engine",
        "Projects",
    });

Public と Private の違いはわかりにくいですが、依存している Module の Include path を追加するかどうかの違いとなります。

例えば GameModule を参照している他の MainModule があったとします。

// GameModule.Build.cs
using  UnrealBuildTool;

namespace UnrealBuildTool.Rules
{
    public class GameModule : ModuleRules {
        public GameModule( ReadOnlyTargetRules Target ) : base( Target )
        {
            PublicDependencyModuleNames.AddRange( new string[] {
                    "Core",
                });
        }
    }
}

// MainModule.Build.cs
using  UnrealBuildTool;

namespace UnrealBuildTool.Rules
{
    public class MainModule : ModuleRules {
        public MainModule( ReadOnlyTargetRules Target ) : base( Target )
        {
            PrivateDependencyModuleNames.AddRange( new string[] {
                    "GameModule",
                });
        }
    }
}

このとき GameModule の Core は PublicDependency なので、MainModule の include path に Core が含まれます。もし GameModule の Core が Private なら MainModule の include path に Core は含まれません。

つまり、他の Module に公開したいヘッダファイルがある場合、ヘッダ側で include している Module は Public にしておく必要があります。他の Module から参照されることがない GameProject のような Module (PRIMARY_GAME_MODULE) では、すべて Private 宣言にして構いません。


●外部ライブラリを参照する場合

UnrealBuildTool は "ThirdParty" というフォルダを特別扱いします。このフォルダは検索対象から外れており、ソースコードがあっても勝手にビルドを行いません。外部ライブラリは一般的に ThirdParty フォルダに入れておきます。Build.cs では下記のように相対的に ThirdParty のパスを求めます。

using  UnrealBuildTool;

namespace UnrealBuildTool.Rules
{
    public class GamePlugin : ModuleRules {
        private string ThirdPartyPath
        {
            get { return Path.GetFullPath( Path.Combine( ModuleDirectory, "../../../ThirdParty/" ) ); }
        }

Include path, Lib path, Lib file 等は個別に指定が必要で、さらに Platform も複数あるので外部ライブラリの参照は複雑になりがちです。

using  UnrealBuildTool;
using  System.IO;
using  System.Collections.Generic;

namespace UnrealBuildTool.Rules
{
    public class GamePlugin : ModuleRules {
        private string ThirdPartyPath
        {
            get { return Path.GetFullPath( Path.Combine( ModuleDirectory, "../../../ThirdParty/" ) ); }
        }
        private Dictionary<UnrealTargetPlatform,string> PlatformTable= new Dictionary<UnrealTargetPlatform,string>(){
            {   UnrealTargetPlatform.Win64,     "Windows/x64",  },
            {   UnrealTargetPlatform.Win32,     "Windows/x86",  },
            {   UnrealTargetPlatform.Linux,     "Linux/x64",    },
            {   UnrealTargetPlatform.Android,   "Android28",    },
            {   UnrealTargetPlatform.Mac,       "macOS/x64",    },
            {   UnrealTargetPlatform.IOS,       "iOS/arm64",    },
        };
        public GamePlugin( ReadOnlyTargetRules Target ) : base( Target )
        {
            PublicDependencyModuleNames.AddRange( new string[] {
                    "Core",
                    "CoreUObject",
                    "Engine",
                    "Projects",
            }
            if( !PlatformTable.ContainsKey( Target.Platform ) ){
                return;
            }
            bool debug= Target.Configuration == UnrealTargetConfiguration.Debug && Target.bDebugBuildsActuallyUseDebugCRT;
            string  config= debug ? "Debug" : "Release";
            string  PlatformName= PlatformTable[ Target.Platform ];

            PublicIncludePaths.AddRange( new string[] {
                    Path.Combine( ThirdPartyPath, "flatlib" ),
                });
            if( Target.Platform == UnrealTargetConfiguration.Android ){
                PublicLibraryPaths.AddRange( new string[] {
                        Path.Combine( ThirdPartyPath, "flatlib/lib", PlatformName, "arm7", config ),
                        Path.Combine( ThirdPartyPath, "flatlib/lib", PlatformName, "arm64", config ),
                        Path.Combine( ThirdPartyPath, "flatlib/lib", PlatformName, "x86", config ),
                        Path.Combine( ThirdPartyPath, "flatlib/lib", PlatformName, "x64", config ),
                    });
            }else{
                PublicLibraryPaths.AddRange( new string[] {
                        Path.Combine( ThirdPartyPath, "flatlib/lib", PlatformName, config ),
                    });
            }
            PublicAdditionalLibraries.Add( "flatCore" );
        }
    }
}

外部ライブラリを必要としている Module や Plugin があれば、それぞれの Build.cs に記述しておく必要があります。Makefile の include のように共通の設定を動的に読み込む仕組みがあれば良いのですが、特に用意されていないようです。


●UnrealBuildTool による Build.cs の読み込み方

*.Build.cs は UnrealBuildTool によって dll に変換されます。


 (1) Intermediate/Build/BuildRules/~.dll を読み込む

 (2) もし *.Build.cs が更新されている場合は動的にコンパイルを行い dll を Reload する


この dll の生成は Project 単位で行います。例えば GameProject の場合、下記のファイルをまとめてコンパイルし単一の GameProjectModuleRules.dll が作られます。

GameProjectEditor.Target.cs
GameProject.Build.cs
GameModule.Build.cs
MainModule.Build.cs

  → GameProject/Intermediate/Build/BuildRules/GameProjectModuleRules.dll

Engine も同様で、下記の cs ファイルから単一の dll にコンパイルします。

Engine/Source/UE4Editor.Target.cs
Engine/Plugins/~/*.Build.cs
Engine/Source/~/*.Build.cs

  → Engine/Intermediate/Build/BuildRules/UE4Rules.dll

よって動的な include はできないものの、他の Build.cs や Target.cs で宣言したコードを呼び出すことが可能です。例えば代表 Module を 1つ決めて、Build.cs に共通で使いたいコードを書いておきます。 

// GameProject.Build.cs
using  UnrealBuildTool;
using  System.IO;
using  System.Collections.Generic;

namespace UnrealBuildTool.Rules
{
    public class ThirdPartyCommonLibrary {

        ~

        public static ThirdPartyCommonLibrary Create( ModuleRules rules, ReadOnlyTargetRules target, string path= null )
        {
            ~
        }
        public void SetupFlatlib()
        {
            ~
        }
    }

    public class GameProject : ModuleRules {
        public GameProject( ReadOnlyTargetRules Target ) : base( Target )
        {
            PublicDependencyModuleNames.AddRange( new string[] {
                    "Core",
                    "CoreUObject",
                    "Engine",
            }
            var lib= ThirdPartyCommonLibrary.Create( this, Target );
            lib.SetupFlatlib();
        }
    }
}

他の Module の *.Build.cs からも参照できます。これでメンテしやすくなりすっきりしました。

// GameModule.Build.cs
using  UnrealBuildTool;

namespace UnrealBuildTool.Rules
{
    public class GameModule : ModuleRules {
        public GameModule( ReadOnlyTargetRules Target ) : base( Target )
        {
            PublicDependencyModuleNames.AddRange( new string[] {
                    "Core",
                    "CoreUObject",
                    "Engine",
            }
            var lib= ThirdPartyCommonLibrary.Create( this, Target );
            lib.SetupFlatlib();
        }
    }
}



<<前のページ(日付が新しい方向) | 次のページ(日付が古い方向)>>