Unreal + MRTKまだ使っていない？ならとりあえずやってみようハンズオン資料(Tokyo HoloLens ミートアップ Vol.23)

# 皆でUnreal EngineでHoloLens 2アプリ開発をやってみよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/247fe7fe-a845-9fc0-cae1-e70285a31be3.png)
Hololens 2がリリースされてからしばらくしてUnreal Engineでの開発がサポートされました。今回は[Tokyo HoloLensミートアップ vol.23](https://hololens.connpass.com/event/193926/)の中で実際にハンズオン形式でやってみようとなったので以前整理したものを少しアレンジして手順として再整理しました。ぜひ皆さん一緒にやってみましょう！

---
## ハンズオンをとして体験できるもの

今回は以下を目的にしています。

* Unreal EngineでHoloLens開発やってみたい
* Mixed Reality Toolkit - UX Tools for Unrealを使って開発したい

このセションが終わったころには
<font color = "red"><strong>Unreal Engine + MRTK UX Tools for Unrealを完全に理解した:smirk:</Strong> </font>
とTwitterで動いた結果と共につぶやいている状態になっているはずです。

---

## 目次

今回は以下の手順で進めます。

* <font size='0'>環境構築(事前実施済)</font>
* 開発
 1. HoloLens開発にに必要なプラグインの導入
 2. ベースとなる空プロジェクトの構築
 3. UX Tools for Unrealの導入とハンドインタラクションの設定
 4. つまんで投げれる物体、サイズを変えて鑑賞できる物体、ボタンでリセットするボタンを作る
 5. 動かしてみる（Unreal上）
 6. HoloLensへデプロイ準備
 7. <font color="red">UX Tools for Unreal完全に理解したとつぶやく&この記事に「LTGM」する（どのくらい成功したかの参考にしたい）</font>
 8. デプロイして動かしてみる（持ってる人）


---

## 開発環境

今回の開発環境は以下の通りです。

* Windows 10 Pro OSバージョン1909
* Unreal Engine 4.25.4
    * HoloLensオプション導入済み
* [Mixed Reality Toolkit - UX Tools for Unreal v0.10.0](https://github.com/microsoft/MixedReality-UXTools-Unreal/releases/tag/v0.10.0)
* Visual Studio 2019(16.5.3)
  * 必要なワークロード/コンポーネント  
    * C++ によるデスクトップ開発
    * .NET デスクトップ開発
    * ユニバーサル Windows プラットフォームの開発
    * MSVC v142 - VS 2019 C++ ARM64 ビルド ツール (v14.25)
    * USBデバイスの接続（有線でデプロイする場合）
* Windows SDK 10.0.18362.0  

---

## 開発ツールの事前準備
Unreal Engineでの開発時にいくつかコンポーネントをセットしておく必要があります。開発の前にツールへの導入を行ってください。

---

### Unreal Engine
Unreal EngineでHoloLens 2アプリを開発する場合はオプション「HoloLens 2」の追加が必要です。以下の通り追加を実施します。

1. [Epic Games Launcher]を起動し、[ライブラリ]タブのインストール済みのエンジンを探し起動横の[▼]で表示されるメニューから[オプション]を選択します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/e9cb9979-a7f5-fe48-9be7-fe017b4cc3ec.png)
2. [Unreal Enghine 4.25.2]インストールオプションが表示されるので[HoloLens 2]にチェックを入れて[適用]を押します。  
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/4f63e485-b215-196d-8d67-0a4619859216.png)

以上でUnreal Engineのセットアップは完了です

---

### Visual Studio 2019のセットアップ
Visual Studioには以下のワークロードおよび、コンポーネントが必要になります。
導入漏れがある場合は追加でセットアップをします。

1. インストーラを起動し、該当のVisual Studioの変更を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/4d4ec828-bf74-f8c8-96fb-3298236d9d2c.png)
2. [ワークロード]から[.NETデスクトップ開発][C++によるデスクトップ開発][ユニバーサルWindowsプラットフォーム開発]の3つをチェックします。<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/24583185-4b53-c9be-9121-146125b184b1.png" width="50%" height="50%"/>
3. [個別コンポーネント]から[MSVC v142 - VS 2019 C++ ARM64 ビルド ツール (v14.25)]をチェックします。このコンポーネントはその時の最新のものを使用します(今回はv14.25)<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/9fa4fab7-032c-d4de-b116-e0e8833d83ea.png" width="50%" height="50%"/>
4. HoloLens 2と開発機を優先で接続する場合は[USBデバイスの接続]もチェックしてください。<br><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/12c2d2a9-37c4-ad69-93e7-125696659ab3.png" width="50%" height="50%"/>

以上でVisual Studioの設定は完了です。
次から実際の開発に入っていきます。

---

## 開発

今回はサンプルとして以下の機能を実装したアプリを作成します。

* ハンドトラッキングで移動ができるCubeを作成する
* サイズ、回転ができるCubeを作成する
* Cubeの横にUX ToolsのSimpleButtonを追加
* SimpleButtonを押すとCube達の初期位置が元に戻る

非常にシンプルなアプリですが、UXTools for UNREALを使ったHololens 2アプリの基本的なことを理解できると思います。

---

## 開発 - 工程

作業は大きく16工程あります。

1. プロジェクト作成～プラグイン設定
8. MRTK UX-Toolsの導入
2. 空のレベルを作る（シーンみたいなもの）
3. 初期位置と光源の設定
4. ユーザオブジェクト(装着者)の追加
5. ゲームモードの作成(オブジェクト定義)
6. プロジェクト設定
7. ARSessionの開始と終了処理
9. ハンドインタラクションの設定
10. 移動（投てき）できるCubeを作成(Uxt Generic Manager)
11. サイズ、回転ができるCubeを作成(Uxt Bouding Control)
12. ボタンを押してリセットする実装を入れる
13. デバッグ実行してみましょう。
14. Twitterで勝利宣言 & LTGM
15. ビルドのためのプロジェクト設定
16. ビルド&デプロイ

手順15,16はスペックによってビルド時間がかかるため（5～10分)

---

### 1. プロジェクト設定 & プラグイン設定

まず最初にプロジェクトの作成～プラグインの設定までを実施しましょう。
大きくは以下の3つの手順で実施します。

* プロジェクトの作成
* プロジェクトの設定
* プライグインの設定（設定後再起動）

Unreal EngineでHololens 2の開発を進めるためにはプラグインとして[HoloLens],[Microsoft Windows Mixed Reality]を設定しておく必要があります。まずは、プロジェクトの作成後、これらのプラグインの設定を実施しましょう。

---


1. プロジェクトの作成をします。カテゴリは[Games]を選択し、[Next]を押します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/bbf8e7c2-6ca8-df6c-488f-dae0f5705119.png)
2. [Template]は[Blank]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/85f3e634-ab05-1b14-0d60-8bad16d780c2.png)
3. [Project Settings]は以下の通りとします。<ul><li>[C++]</li><li>[Scalable 3D or 2D]</li><li>[No Sarter Content]</li></ul>上記を設定の上、[Name]を変更し[Create Project]を押します。<br>途中でVisual Studioも起動されると思いますが放置で問題ないです。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/428ff90f-9444-2e75-6c96-d6d5818ce155.png)
4. メニューから[edit]-[Plugins]を開きます。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/50bc288e-59d1-1856-593b-9b2549540286.png)
5. Pluginパネルが開いたら、[Augmented Reality]-[HoloLens]にチェックを入れます。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/79805460-7464-6fd3-6850-2bebf1301426.png)
6. 続いて、[Virtual Reality]-[Microsoft Windows Mixed Reality]にチェックを入れます。<br>チェックが終わればエディタを終了してください。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/b28c8dcd-59ac-8c75-f05a-1fb44ccfbaa5.png)

次に、MRTK UX-Toolsの導入を行います。

---

### 2. MRTK UX-Toolsの導入

UXTools-Unrealはプロジェクトにプラグインとして導入します。
※最近、β版としてマーケットプレースで公開されており、これをエンジンにインポートしておくことでプラグインとして導入可能になりました。

1. GitHubからクローンまたはソースコード一式をダウンロードします。
2. 先ほどUnreal Engineで作成したプロジェクトをエクスプローラーなどで開きます。
3. クローンしたソースコードの中にある[UXToolsGame/Plugins]をプロジェクトのフォルダー直下にコピーします。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/d9863a35-936f-05f1-9021-86ffac5dc697.png)

以上で、導入は完了です。UXToolsのビルドをするかの確認ダイアログが表示された場合は実施するを選択してください。

---

### 3. 空のレベルを作る（シーンみたいなもの）
次にUnityではシーンに相当するレベルを作成します。

1. [File]-[New Level...]を選択し、新しいレベルを作成します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/67a1b67c-b445-607c-6b11-5654cbf3a84d.png)
2. タイプの選択ダイアログが表示されるので[Empty Level]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/c85dcd0c-cf4b-43eb-d2e5-e4b7daed8bd8.png)
3. [Save Current]を押して、レベルを保存します。名前は[Main]にしておきましょう。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/bdf975ca-88d7-8ccb-5ed1-8f77bded8925.png)

---

### 4. 初期位置と光源の設定

次にPlayerのスタート位置と光源を設定します。

1. [Place Actor]パネルから、[Basic]-[Player Start]を選びエリアにドラッグ&ドロップします。
2. [World Outliner]から先ほど追加した[PlayerStart]を選択し[Details]-[Transform]の[Location]を(0.0,0.0,0.0)に設定します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/053fcd86-0fbd-ce08-f02a-35d787adf519.png)
3. [Place Actor]パネルから、[Basic]-[Player Start]を選びエリアにドラッグ&ドロップします。
4. [World Outliner]から先ほど追加した[DirectionLight]を選択し[Details]-[Transform]の[Location]を(430.0,0.0,340.0)に設定します。
5. [Details]-[Transform]の[Rotation]を(0.0,-45,0.0)に設定します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/f47d88d9-5fbd-be5d-ed11-c99e6336807f.png)

以上でUnityでいうところのシーンの初期状態までが完了です。次からコンテンツの作成に進んでいきます。

---

### 5. ユーザオブジェクト(装着者)の追加

次にHoloLens 2の装着者を表すオブジェクトを生成します。


1. [Content Browser]パネルを選択し、[Add New]-[Blueprint Class]を押します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/b65bbead-e46e-561f-576e-c9ce6696473b.png)
2. [Pick Parent Class]ダイアログが表示されるので、[All Classes]から[Default Pawn]を選択し、名前を[MRPawn]にします。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/479825cd-37db-8aef-6e65-803c0f91e8bf.png)
3. [Content Browser]内の[MRPawn]を選択し、右クリックで表示される、メニューから[Edit]を選びます。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/930330f2-fa98-50d6-091b-18760377f176.png)
4. [Class Defaults]の中から、以下のコンポーネント内の[Collision Presets]パラメータを[NoCollision]に設定します。<ul><li>[CollisionOmponent]</li><li>[MeshComponent]</li></ul>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/3b2e47e9-f13f-f1dc-bd08-da2d9247943e.png)
5. [Compile]を行い、[Save]を押して閉じます。

以上で、ユーザオブジェクトの作成は完了です。次にこれを実際のアプリの中で使うために必要なゲームモードの作成に移ります。
   
---

### 6. ゲームモードの作成(オブジェクト定義)

実際のアプリの中で使うために必要なゲームモードの作成を行います。装着者に相当するPawnクラスを自作したのでこれを利用できるよう設定します。


1. [Content Browser]パネルを選択し、[Add New]-[Blueprint Class]を押します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/b65bbead-e46e-561f-576e-c9ce6696473b.png)
2. [Pick Parent Class]ダイアログが表示されるので、[Game ModeBase]を選択し、名前を[MRGameModeBase]にします。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/ae90998b-af9d-e7bd-3a9a-ec2ffc111bcd.png)
3. [Content Browser]内の[MRGameModeBase]をダブルクリックして編集画面を開きます。[Details]内の[Classes]-[Default Pawn Class]に[MRPawn]を設定します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/4bd0210b-dd4a-d2d6-cb7d-113019124d74.png)
4. [Compile]を行い、[Save]を押して閉じます。

以上で完了です。次に作成したマップとゲームモードをプロジェクトで使用するように設定します。

---

### 7. プロジェクト設定

次にプロジェクト設定をします。

1. メニューから[Edit]-[Project Settings...]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/e1e57d17-b370-7f76-bd6b-30bd40f7b37b.png)
2. [Project]-[Maps & Modes]を選択します。[Default GameMode]を[MRGameModeBase]に、[Editor Startup Map][Game Default Map]の両方を[Main]に設定します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/de0cf03b-bf5a-8b1d-1365-858c014425d9.png)

以上で、実行時に今回作成したマップが利用されアプリケーションになります。次はHoloLens向けに必要なアプリの開始と終了処理を実装します。

---

### 8. ARSessionの開始と終了処理

次はアプリ実行に必要な初期設定を行うためのARSessionの開始と終了を設定します。


1. [Content Browser]パネルを選択し、[Add New]-[Miscellaneous]-[Data Asset]を押します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/6f643f0e-c2af-6377-8782-25e5c798a136.png)
2. [Pick Data Asset Class]ダイアログが表示されるので、[ARSessionConfig]を選択し[Select]を押します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/93ecc4bc-2299-8527-c40f-a5a646a91e2e.png)
3. [Content Browser]に追加されます。名前を[ARSessionConfig]にして保存します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/15d4d7f0-9a61-8244-dc8c-28f6aa0b85f6.png)
4. [Content Browser]パネル内の[ARSessionConfig]をダブルクリックで開き、**パラメータを変更せずに**[Save]を押して保存します。
5. [Bluepoints]-[Open Level Bluepoint]を選択しEvent Graphを表示します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/9a369f70-8390-dbd5-385f-241cb175ce3d.png)
6. [Event Graph]内の[Event BeginPlay]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a4a26bfc-e4e3-cb7f-2352-334364647c04.png)]をドラッグして[Event Graph]内の空いてるところでドロップします。
7. [Executable Actions]が開きます。中から[Start AR Session]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/ebfc1ed6-2b25-50bc-8214-e9dcc389347e.png)
8. [Start AR Session]が追加されます。枠の中に[Session Config]パラメータがあるので先ほど作成した[ARSessionConfig]を設定します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/bbbc424b-131b-77fb-35f2-f0b057022573.png)
9. [LEVEL BLUEPRINT]内の任意の場所で右クリックをして[All Actions for Blueprint]メニューを表示し[Event End Play]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/86ee9521-c26c-17bf-a5ef-b9bbaf206b29.png)
10. [Executable Actions]が開きます。中から[Stop AR Session]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/d77d85d0-bdca-d4af-80ab-7320899744f5.png)
11. パネル上部の[Compile]を押下後[Save]を押下して保存します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/23007ade-c24c-6335-524d-dda7ae6d9262.png)

以上で、Hololens 2実行に必要な初期処理の設定が完了です。設定完了時には以下のようになっていることを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/cfac607d-4800-42f4-ea94-41e4a4ce7eba.png)

---

### 9. ハンドインタラクションの設定

ハンドインタラクションは以下のようにアプリケーション内でハンドトラッキングの状況を可視化するために設定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/4fba4165-d053-313f-a029-34b6e4cceec9.png)

少し設定が複雑なので先に完成形を出しておきますので参考にしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/ddc62c30-3b71-05f8-5af8-1597b77760b0.png)

1. [Content Browser]内の[MRPawn]を選択し、右クリックで表示される、メニューから[Edit]を選びます。
2. [Event Graph]タブを表示して、[Event BeginPlay]以外のイベントを削除します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/930330f2-fa98-50d6-091b-18760377f176.png)
3. [Event Graph]内の[Event BeginPlay]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a4a26bfc-e4e3-cb7f-2352-334364647c04.png)]をドラッグして[Event Graph]内の空いてるところでドロップします。
4. [Executable Actions]が開きます。中から[Spawn Actor from Class]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/1b634398-0a17-eb95-2adf-d5f13dd0cee5.png)
5. 追加された[Spawn Actor from Class]の[Class]プロパティに[UxtInteractionActor]を選択します<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/90504894-8563-b42a-f908-665a4096e474.png)
6. [Spawn Actor from Class]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a4a26bfc-e4e3-cb7f-2352-334364647c04.png)]をドラッグして[Event Graph]内の空いてるところでドロップし、[Uxt Interaction Actor]-[Set Hand]を追加します(Set Handは複数あるので注意！！！)。
7. [Set Hand]の[Hand]プロパティに[Left]を選択します。
8. [Spawn Actor from Class]-[Return Value]と[Set Hand]-[Target]をノードでつなぎます。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/744fb1e5-c6e3-742d-cebf-405971b7c204.png)
9. [Set Hand]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a4a26bfc-e4e3-cb7f-2352-334364647c04.png)]をドラッグして[Event Graph]内の空いてるところでドロップします。
10. 手順.4～6までを繰り返して同じ設定を追加します。
11. [Set Hand]の[Hand]プロパティに[Right]を選択します。
12. [Spawn Actor from Class]-[Return Value]と[Set Hand]-[Target]をノードでつなぎます。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/d0912e8b-9957-6dc6-f2fb-68a0a5afea9d.png)
12. [Spawn Actor from Class]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/cec2d1e4-a482-9726-15f6-d86b9748ac9b.png)]をドラッグして[Event Graph]内の空いてるところでドロップし、[Make Transform]を追加します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/56717197-02fc-58d3-98d6-f93561eced67.png)
13. もう一方の[Spawn Actor from Class]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/cec2d1e4-a482-9726-15f6-d86b9748ac9b.png)]も接続します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/146b9ccd-12c5-7906-c266-ea922281cf3f.png)
14. [Spawn Actor from Class]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/e3bc4c68-7c80-fce6-6775-51830ed64416.png)]をドラッグして[Event Graph]内の空いてるところでドロップし、[Get a reference to self]を追加します。合わせてもう一方の[Spawn Actor from Class]-[Owner]も接続します。
15.  [Compile]を行い、[Save]を押して閉じます。

以上でハンドインタラクションの表示に関する設定が完了です。

---

### 10. 移動（投てき）できるCubeを作成(Uxt Generic Manager)

移動（投てき）できるCubeを作成します。cubeにはMRTKの[Uxt Generic Mnipulator]コンポーネントを追加します。このオブジェクトをセットしたアクターはハンドトラッキングで操作可能になります。

1. [Place Actor]パネルから、[Basic]-[Cube]を選びエリアにドラッグ&ドロップします。
2. [World Outliner]から先ほど追加した[Cube]を選択し[Details]-[Transform]の[Location]を(100.0,-20.0,0.0)に設定します。<br>注：Unityとは座標系の単位が違うので注意。Unityの1単位1m,Unreal Engineの1単位1cm
3. [Details]-[Transform]の[Scale]を(0.2,0.2,0.2)に設定します。
4. [Details]-[Transform]の[Mobility]を[Movable]に変更します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/1b83c2a9-fba3-b7a0-24b2-e4e2b362999e.png)
5.追加したCubeの[details]-[Physics]を探し、以下のパラメータを変更します。<ul><li>Simulate Physics をtrue</li><li>Enable GravityをFalse</li></ul>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/754448d4-3843-6dbf-917e-5bc80edb325a.png)
6. [Details]-[Add Component]を選択し、[Uxt Generic Mnipulator]を追加します。<br>ポイント1：Uxt Generic ManipulatorはMRTK for UnityでいうObject Mnipulatorです。<br>ポイント2：コンポーネントなどプレフィックスが”Uxt”のものがUXTool for Unreal用のコンポートです<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/4d311ba4-7d83-af6b-b4a2-5ccf736ffaae.png)


---

### 11. サイズ、回転ができるCubeを作成(Uxt Bounds Control)

次に、操作する対象としてCubeを作成します。cubeにはMRTKの[Uxt bounds Control]コンポーネントを追加します。このオブジェクトをセットしたアクターはBounding Controlが有効になり、サイズ変更/回転等操作が可能になります。

1. [Place Actor]パネルから、[Basic]-[Cube]を選びエリアにドラッグ&ドロップします。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/1b83c2a9-fba3-b7a0-24b2-e4e2b362999e.png)
2. [World Outliner]から先ほど追加した[Cube]を選択し[Details]-[Transform]の[Location]を(100.0,20.0,0.0)に設定します。<br>注：Unityとは座標系の単位が違うので注意。Unityの1単位1m,Unreal Engineの1単位1cm
3. [Details]-[Transform]の[Scale]を(0.2,0.2,0.2)に設定します。
4. [Details]-[Transform]の[Mobility]を[Movable]に変更します。
5. [Details]-[Add Component]を選択し、[Uxt bounds Control]を追加します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/821a40f9-ebe8-599f-e511-3217cd770aaa.png)


以上でオブジェクトの定義は終わりです。

---
### 12. ボタンを押してリセットする実装を入れる

MRTK UX Tools for UnrealのPressable Buttonを利用してボタンを押すと操作したオブジェクトの位置がリセットされる処理を追加します。
完成後の状態は以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/ec4e56be-7fe1-820e-7921-b2df556933ad.png)


1. [Content Browser]パネルを選択し、[Add New]-[Blueprint Class]を押します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/b65bbead-e46e-561f-576e-c9ce6696473b.png)
2. [Pick Parent Class]ダイアログが表示されるので、[All Classes]から[UxtPressableButtonActor]を選択し、名前を[PressableButton]にします。<BR>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/603a773e-c975-c3cd-4875-a7e968c5bfb0.png)
3. [Content Browser]内の[PressableButton]をエリアにドラッグ＆ドロップします。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/b6fe20d0-1560-01fc-3b5f-24296b240b0f.png)
4. [World Outliner]から先ほど追加した[PressableButton]を選択し[Details]-[Transform]の[Location]を(50.0,-30.0,10.0)に設定します。
5. [Details]-[Transform]の[Rotation]を(0.0,0.0,180.0)に設定します。
6. [Details]-[Transform]の[Scale]を(3.0,3.0,3.0)に設定します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/32d89aa7-3d98-587d-82fd-7fb08e661732.png)
5. [Content Browser]内の[PressableButton]をダブルクリックして、[Event Graph]を開きます。デフォルトでセットされているイベントをすべて削除します。
6. [Component]タブ内の[Pressable Button]を選択し[Details]タブの下の方にある[Events]の中から[On Button Pressed]の横の[+]ボタンを押してイベントを追加します。<BR>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/59ad94c5-32ee-97c3-53cf-01a483ca9e43.png)
7. [On Button Pressed]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a4a26bfc-e4e3-cb7f-2352-334364647c04.png)]をドラッグして[Event Graph]内の空いてるところでドロップし、[Set Actor Location And Rotation]を追加します。
8. [New location]を(100.0,-20.0,0.0)に設定します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/807f7444-e857-a17e-83cf-2fe29b31137d.png)
8. [Set Actor Location And Rotation]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a4a26bfc-e4e3-cb7f-2352-334364647c04.png)]をドラッグして[Event Graph]内の空いてるところでドロップし、[Set Physics Linear Velocity(BackPlateMeshComponent)]を追加します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/dc4401ff-eea0-6c9f-510f-478e21ddc2e3.png)
9. 追加した[Set Physics Linear Velocity]の[Target]に紐づく[Back Plate Mesh Component]を削除します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/b5af3aaa-4c37-1fab-3bf9-42db9e3fd091.png)
10. [Set Physics Linear Velocity]の[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/a4a26bfc-e4e3-cb7f-2352-334364647c04.png)]をドラッグして[Event Graph]内の空いてるところでドロップし、[Set Physics Angular Velocity in degrees]を追加します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/89713759-6f53-c1a1-a213-68f961b7cf6a.png)
9. [My Blueprint]タブ内の[Variables]の[+]ボタンを押して、変数を2つ追加します。名前は[ManipulateCube1]にしましょう。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/10a735a1-5592-fc27-d0c4-e92e20b95aa4.png)
10. [Variable]-[ManipulateCube1]を選択し、[Details]-[Variable Type]の型を[Static Mesh Actor]変更します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/77d7c15d-c9e2-fcfd-f56c-307446691bc5.png)
11. [Instance Editable]にチェックを入れます。
12. [My Blueprint]タブ内の[Variables]-[ManipulateCube1]を[Event Graph]内にドラッグ＆ドロップします。GetかSetの選択肢が出てくるので、[Get Cube]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/0c21d9f6-2013-7fba-9866-e9b95163e3b7.png)
13. [Event Graph]内の[ManipulateCube1]と次の3つをつなぎます。<ul><li>[Set Actor Location And Rotation]-[Target]</li><li>[Set Physics Linear Velocity]-[Target]</li><li>[Set Physics Angular Velocity in degrees]-[Target]</li></ul>
14. [Compile]を行い、[Save]を押して閉じます。
15. [World Outliner]パネル内の[PressableButton]を選択し、[Details]パネル内の[Default]-[Cube]に[Main]-[Cube]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/00fcbb50-39fe-c047-27c3-4218304e4dce.png)
16. [Save Current]を押して保存します。

以上で、必要な実装が完了しました。

---

### 13. デバッグ実行してみましょう。
#### デバッグ実行(Unreal Engine上)

早速動かしてみましょう。上部メニューから[Play]を押すとデバッグが開始されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/19bbee4a-4297-be25-e63c-73ac12936b41.png)

実行すると下記のように左側にボタン、操作するCube、両手のモデルが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/9629fc26-1f24-810b-ef79-6b9c223e01c7.png)


エリア内をクリックするとデバッグ操作が可能になります。手の操作は以下の通りです。操作方法はUnity版と同じ動作です。

|操作|動作|
|:-:|:--|
|shift|左手操作|
|alt|右手操作|
|shift(alt)+マウス移動|手の移動(上下左右)|
|shift(alt)+ホイールマウス|手の移動(前後)|
|shift(alt)+左クリック|Hold⇔Hold解除<br>※押す度に切り替わります。|

#### デバッグ実行(Holographic remoting)

HoloLens / HoloLens 2にリモートで接続してデバッグを行う「HoloGraphic Remoting」も実施可能です。
この方法だと、動作確認もしやすいのでお勧めです。設定については次の通りです。

1. メニューから[Edit]-[Project Settings...]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/e1e57d17-b370-7f76-bd6b-30bd40f7b37b.png)
2. [Platforms]-[Microsoft Windows Mixed Reality]を選択します。[Holographic Remoting]-[Enable Remoting For Editor(Required Restart)]にチェックを入れます。エディタの再起動を要求されるので再起動を行います。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/0ad38ec8-af78-e00c-e309-1fe906f2e456.png)
3. HoloLensに[Holographic Remoting]をインストールする。

以上で設定は完了です。引き続きHoloLensとの接続を行います。接続には「有線(USB)」「無線(Wifi)」いずれの方法も利用できます。

##### 有線(USB)接続の場合

HoloLensと有線で接続する場合は **付属のUSBケーブルを使用** し、かつ **Visual Studioのコンポーネント「USBデバイスの接続」を実施**しておく必要があります。

1. PCとHoloLensをUSBで接続する。
2. HoloLensのWifiを切断する（念のため）
3. HoloLens 2側でHolographic Remotingを起動し表示されるIPアドレスを控えておく。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/d4aa73e0-4946-9f4c-1a22-7be974a80901.png)
4. もう一度、[Platforms]-[Microsoft Windows Mixed Reality]を選択します。今度は[Holographic Remoting]の中で赤字で[Disconnected]と表示されているのがわかるかと思います。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/9969e743-31d1-3421-c6ba-7d5a1e85146e.png)
5. [IP of HoloLens to remote to.]に先ほど控えたIPアドレスを入力します。
6. 上部の[Connect]を押します。正常に接続できると緑色で[Connected]と表示されます。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/25857911-8649-85f6-5f5d-d5756baa5f78.png)
7. メニューから[Active Play Mode]-[VR Preview]を選択します。自動的にデバッグ実行が開始されます（以降は[VR preview]で実行されるのでリモートデバックが完了したらもとに戻しておきましょう）。実行するとPC側にはHoloLens視点のウィンドウが表示されます。HoloLens側にはアプリの描画が行われているのでデバッグを実行します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/5fa86dae-d0da-dfe1-3378-63cb4e52741f.png)

##### 有線(Wifi)接続の場合

HoloLensと無線で接続する場合も有線と変わりはありません。**PCとHoloLensが同一ネットワーク上にいる状態で**Holographic Remotingを起動しIPアドレスをエディタ側に入力してください。

---

### 14. ビルド用の設定

最後にHoloLens 2にデプロイするための設定を行います。設定自体はUWPアプリに必要な設定と変わらりません。

1. メニューから[Edit]-[Project Settings...]を選択します。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/e1e57d17-b370-7f76-bd6b-30bd40f7b37b.png)
2. [Project]-[Description]を選択し、[About]-[Project Name]に任意のプロジェクト名を入力します。また、[Publisher]-[Company Distinguished Name]に署名用の企業名を記載します（CN=XXXXXXXXX）<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/8af8cfc0-77e0-70e0-6ed8-b781c014226f.png)
3. [Platform]-[HoloLens]を選択し、[HoloLens]-[Build HoloLens Device]をチェックします。また、[Packaging]-[Signing Certificate]に署名を設定します。署名がない場合は横の[Generate new]ボタンを押して生成してください。パスワードの入力ダイアログが表示されますがテスト用であれば無でも問題ありません。<br>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/3d1a0231-751c-9677-bbe0-7782d497c083.png)

---

### 15. ビルド

最後にビルドを実施します。Unreal Engineではパッケージングと呼ばれバックグラウンドでVisual Studioと連携してパッケージ化まで進めてくれます。

<font color="red"><B>とても重要！！！
実はそのままビルド実行しても途中で落ちる場合があります。ログを確認したときに「(UnrealEngineパス)¥engine¥source¥runtime¥core¥public¥Misc/Char.h: error C4819」というエラーが記載されていた場合は、以下に記載している部分のコメントを削除しないと正常にビルドができないため各自に該当箇所のソースコードを削除してください。</B></font>

```c:(UnrealEngineパス)\Engine\Source\Runtime\Core\Public\Misc\Char.h

...
/**
 * Avoid sign extension problems with signed characters smaller than int
 *
 * E.g. 'Ö' - 'A' is negative since the char 'Ö' (0xD6) is negative and gets <<< 127行目付近のこの行を削除
 * sign-extended to the 32-bit int 0xFFFFFFD6 before subtraction happens.
 *
 * Mainly needed for subtraction and addition.
 */
static constexpr FORCEINLINE uint32 ToUnsigned(CharType Char)
{
...
```

メニューより、[File]-[Package Project]-[HoloLens]を選択すると保存先フォルダの選択ダイアログが開くので任意の場所を指定すると、ビルドが開始されます。それなりに時間がかかるので完了するまでしばらく待ちます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/152548/4754d94c-4147-7e7e-ecc5-7e505d1c0e52.png)