はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

~Xamarin.FormsからMAUIへ~ .NET Upgrade Assistantを使って移行してみよう

前回:
hatsune.hatenablog.jp

新規作成したXamarin.Formsのソリューション構造と、新規作成した.NET MAUIのソリューション構造が全く違うことを前回紹介しました。
今回は、新規作成したXamarin.Formsのソリューションを.NET MAUIに移行します。

.NET Upgrade Assistantによる自動移行

今回紹介する方法は、 .NET Upgrade Assistantによる自動移行です。
learn.microsoft.com

.NET Upgrade Assistantのインストール

dotnet tool install -g upgrade-assistant

.NET Upgrade Assistantの実行

upgrade-assistant upgrade .\XamarinApp.sln --non-interactive --entry-point *

実行すると、移行するための操作内容や結果がどんどん表示されますが、かなり作業としては多いようです。
時間もそれなりに時間を要しますので、時間的に余裕のある時に試すのがいいでしょう。
なお、オリジナルのソリューション構成は自動的にバックアップが作成されますので、その点は安心して実行できます。

.NET Upgrade Assistantによる移行結果

.NET Upgrade Assistantを実行した結果を、実行前の状態と比較してます(Gitに事前にコミットしておいて実行後のファイルとの差分を検証)

XAMLファイル関連

Xamarin.Formsの画面定義である拡張子がxamlXAMLファイル関連の変更点としては名前空間の変更があります。

具体的には、Xamarin.Formsの名前空間「xmlns="http://xamarin.com/schemas/2014/forms"」→MAUIの名前空間「xmlns="http://schemas.microsoft.com/dotnet/2021/maui"」の置換が必要です。
基本的には名前空間の変更だけで、画面定義部分であるXAMLの他の部分は変更がかかっておりません。
実際のアプリ開発用プロジェクトでは、それだけでは期待した表示が得られない可能性もありますが、まずは、MAUI上で動作するように変更するポイントはここだけのようです。

XAMLC#部分関連

xamlファイルと対になるxaml.csファイルについても変更点は名前空間のみとなります。

usingのところで参照している「Xamarin」「Xamarin.Forms」を「Microsoft.Maui」「Microsoft.Maui.Controls」に変更します。
usingではなくコード本文中で「Xamarin.Forms.~」のように記載している部分があれば、そこも変更が必要です。
もともとXamarinで作成していたとしても、コード部分は.NET Frameworkと互換性があり、また、.NET Frameworkと.NET 6/7も基本的にコードの互換性はあるので、これだけシンプルな変更となっているのだと推測します。

csproj(プロジェクトファイル)のアップグレード

移行で一番変更がかかるのがこのプロジェクトファイルです。
.NET Framework形式から.NET SDK形式にプロジェクトファイルの変更します。

不安になるくらい要素が削除されます。なぜこのようにシンプルになるのかの答えはlearnにありました。
learn.microsoft.com

.NET Framework プロジェクトとは異なり、既定値がほとんどの一般的なユース ケースに対応しているため、これらの項目をプロジェクト ファイルで指定する必要はありません。 この動作により、プロジェクト ファイルのサイズがより小さく、より簡単に理解できるようになり、必要に応じて手作業で編集できます。

.NET SDK形式のプロジェクトファイルにすることでこのような恩恵を得られるのでシンプルになるわけです。

手動変更

.NET Upgrade Assistantだけで完結してくれたらよかったのですが、一部手動での変更が必要です。

AssemblyInfo.csの削除

AssemblyInfo.csの内容は、csproj側への記載(プロジェクトのプロパティ)に変更が必要です。
AssemblyInfo.csの内容をcsproj側に記載がおわったら、AssemblyInfo.cs自体は削除します。

Resource.designer.csの削除


こちらも.NET SDK契機にすることで不要になるので削除します。

MainActivity.csの変更

Xamarin時代のMainActivity.csの基底クラスは「global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity」でしたが、.NET MAUIにすると「MauiAppCompatActivity」となりますので、MainActivity.csを書き換えます。
OnCreateメソッドの中身も「base.OnCreate(savedInstanceState);」をのこしてFormsなどの初期化ロジックは削除します。

MainApplication.csの追加

Androidプロジェクトに「MainApplication.cs」を追加します。

MauiProgram.csの追加

共通プロジェクト側に「MauiProgram.cs」を追加します。

実機実行

実機実行が非常に大変でした。
アップグレードする前のXamarin.Formsのプロジェクトで実機実行できることを確認しておいたのですが、実行ターゲットに実機がでてこないのです。

<<<<<<調査継続中>>>>>>>

adbコマンドで実機転送して確認

実際に実機で動くのかどうか。とりあえずは、adbを使ってapkファイルを実機転送して実行できるかを試してみましょう。
これができるのであれば、Visual Studio側の問題だと切り分けられます。

実機接続確認

まずは、実機が接続されているか「adb devices」で確認します。

問題なく接続できていますね。

apkファイル作成

adbコマンドで実機転送できるのはapkファイルになります。releaseの生成物をaabではなくapkに変更する方法でもいいのですが、あとで戻し忘れそうなのでdebugで生成したapkを転送してみます。
ただし、debugビルドはファーストデプロイが有効で、ファーストデプロイが有効だとアーカイブ(apkファイル作成
)できないのでそこだけ変更します。

変更ができたら、ソリューションエキスプローラ―でAndroidプロジェクトを右クリックして「アーカイブ」を選択すればapkファイルが作成できます。

apkファイルに署名

apkファイルに署名せずに実機転送しようとすると「INSTALL_PARSE_FAILED_NO_CERTIFICATES」のエラーが出力されるので、アーカイブマネージャーで、[配布]-[アドホック]で署名付きapkファイルを作成します。

apkファイルを実機転送

adb -s L52A1ced3372 install com.companyname.xamarinapp.apk


実機実行

実機でXamarinAppを実行すれば、無事に動作しました。
これであとは、Visual Studioで実機が認識されて実機転送デバックできる手順が分かれば、安心してアップグレードを想定して使い始められそうですね。

.NET MAUIの新規プロジェクト構造について

前回:hatsune.hatenablog.jp

.NET MAUIで何ができるのかを知っていく前に、まずは、Visual Studio 2022を使って、.NET MAUIの新規ソリューションを作成してみましょう。

ターゲットフレームワークは?

.NET 6か.NET 7が選べるようですね。

新規ソリューション構成の違い

新規ソリューション構成(MAUI)

選んだ結果として作成されるソリューション構成は次のような構成です。

プロジェクトが1つで、Platformsフォルダに各種ターゲットごとの定義が含まれています。

新規ソリューション構成(Xamarin.Forms)

一方でXamarin.Formsだと次のような構成です。

アーカイブの作り方(配布形式の作成)

MAUI

どのプラットフォームでも[発行]で配布形式の作成ができます。
プラットフォームの切替はこんな感じで行えます。

例えば、Androidを指定して[発行]をすると従来のXamarinと同様にAndroidプラットフォームのアーカイブが作成されます。

これだけ違うと全面作り直しか?と思ったのですが、どうやらいろいろ調べてみると新規作成時こそソリューション構成は違いますが、Xamarin.Formsから.NET MAUIへの変換パスは(手動も含めて)用意されているようです。
次回は、そのあたりをさらに調べたいと思います。

次回:
hatsune.hatenablog.jp

そろそろ.NET MAUIを始めようか

C#XAMLスマホアプリが構築できるXamarin.Formsが大好きです。
そんなXamarinのサポートも約1年後の2024/5/1に終了します。
dotnet.microsoft.com
Android 13 と Xcode 14 SDK (iOS および iPadOS 16、macOS 13) よりも新しいOSバージョンにはXamarinは対応しないとのことです。
スマホOSは容赦なくバージョンが上がっていきますし、ストアへの登録要件も上がっていきますので後継フレームワークへの移行を考えないといけない時期になってきましたね。

すでに後継フレームワークは発表されています。

  • Xamarin→ .NET 7
  • Xamarin.Forms →.NET Multi-Platform App UI (MAUI)

互換性はあるようですが、非互換もあるようなのでLearnにあるドキュメントを読んで、まずは、移行するための大枠を知っていきたいと思います。
learn.microsoft.com

次回:
hatsune.hatenablog.jp

Nreal Airを買ったのでARCoreを使って6DoF化してみる

前回:
hatsune.hatenablog.jp

準備

開発環境

  • Unity 2021.3.15f1 <---今回から2021.3.14f1から変更
  • Visual Studio 2022 (Community 2019なども可)
  • NRSDK 1.10.5 <---今回から1.9.5から変更

環境整備:詳細は前回参照

  1. NRSDKのインポート
  2. NRSDKのTipsのFix
  3. GraphicsAPI is not OpenGLES3の対応

1.10.0でもOpenGLES3のFixについてはTipsからFixできませんでした。
そこで1.9.5同様に、[Build Settings]の中の[Player Settings]の[Android]-[Other Settings]の項目への設定なので、[Auto Graphics API」チェックを外して、「ES3.1」「ES3.1+AEP」「ES3.2」のチェック

新規プロジェクト作成

新規作成

Unity Hubを起動して[プロジェクト]→[新規作成]をクリックして、プロジェクトの新規作成を行います。

テンプレートの指定

テンプレートとして[3D]を選択して、プロジェクト名を指定したら[作成]をクリックします。

プラットフォームの変更

Unityを起動してUnityの新規プロジェクトが作成されたら、[File]-[Build Settings]メニューから設定画面を開きます。
プラットフォームを「Android」に変更して[Switch Platform]をクリックします。

C#エディタの設定

[Edit]-[Perferences]メニューから[External Tools]の[External Script Editor]で使用するVisual Studioを選択します。
VSCodeなども選べますが、今回は愛用している「Microsoft Visual Studio 2022」を選択しました。

ARCoreの導入

ARFoundationパッケージの導入

Unityの[Window]-[Pakage Manager]メニューで[パッケージマネージャー]ウィンドウを開きます。

[パッケージマネージャー]ウィンドウで「Packages]の場所を「Unity Registry」に切り替えます。

そして、「AR Foundation」と「ARCore XR Plugin」を指定して、ウィンドウ右下の[Install]ボタンでインストールします。

Main Cameraの削除

「MainCamera」は不要なので「Hierarchy」から削除します。

オブジェクト追加

「Hierarchy」を右クリックして、[XR]-[AR Session]メニューをクリックしてAR Sessionを追加します。
同様に[XR]-[AR Session Origin]メニューをクリックしてAR Session Originを追加します。

平面検知の追加

ARFundationで現実空間の平面を検知するには「AR Session Origin」に「ARPlane Maneger」を追加するだけで自動的に平面検知が行えます。
「Hierarchy」で「AR Session Origin」を選択し、「Inspector」で「ARPlane Maneger」を追加します。

検知した平面に平面を表示する

「ARPlane Maneger」が検知した平面は、そのままでは人が見える形で何か表示がされるわけではありません。
そこで、検知した平面に平面を表示するように設定します。
どのような表示かは、「ARPlane Maneger」の「Plane Prefab」に指定した内容できまります。

表示用プレハブフォルダの設置

「Project」に「Prefab」フォルダを作成します。

表示オブジェクトの用意

「Hierarchy」を右クリックして、[XR]-[AR Default plane]メニューであらかじめ用意されている平面オブジェクトを追加します。

表示オブジェクトをプレハブ化

「Hierarchy」に追加された「AR Default plane」を「Project」-「Prefab」フォルダにドラッグ&ドロップしてプレハブ化します。

「Hierarchy」上の「AR Default plane」は不要なので削除しておきます。

AR Session Originに表示用プレハブを指定


Player Settingsの設定

[Fille]-[Build Settings]-[Player Settings]で設定ウィンドウを開いたら、Androidの[Other Settings]の中にある設定を変更します。

Graphics APIs から Vulkan を削除

[Graphics APIs」から「Vulkan」を削除します。

Minimum API Levelの変更

Minimum API Levelを7.0以上に変更します。

XR Plug-in Managementの設定

[Edit]-[Project Settings]で設定ウィンドウを開いたら、[XR Plug-in Management]で[ARCore]にチェックを入れてARCoreの初期化するように指定します。

ARFoundationとNRSDKを接続する

ARFoundationで検出したスマホ側の6DoF検知した結果をNreal Airの移動(足りない3DoF分)に反映することで、Nreal Airを疑似的に6DoFにすることができます。
この辺りは、ホロラボのたるこすさんがすでに実現していて、今回は、その方法を教えてもらって実装しました。


今回、たるこすさんのご厚意でブログでの記載OKいただきましたので、その方法について少し解説します。

オブジェクト配置

NRCameraRigParentの配置

[Hierarchy]で「AR Session Origin」を右クリックして[Create Empty]メニューで空のゲームオブジェクトを配置し、「NRCameraRigParent」という名前を付けます。

NRCameraRigの配置

[Assets]-[NRSDK]-[Prefabs]にある「NRCameraRig」を[Hierarchy]の「AR Session Origin」にドラッグアンドドロップします。

Cubeの配置

[Hierarchy]を右クリックして、[3D Object]-[Cube]メニューでCubeをARFoundationの管理下で配置します。

Positionは(0, 0, 1)、Rotationは(30, 30, 0)、Scaleは(0,2, 0.2, 0.2)として、1m先に少し回転した立方体を配置します。

スクリプト作成

NRCameraRigParentに、ARFoundationカメラ(スマホカメラ)と移動をNRSDKカメラ(NrealAirの視野に相当)の移動に反映するスクリプトを記載します。
gist.github.com
このスクリプトのキモは「GetYawRotation」メソッドを使って、スマホ水平方向の回転と Nreal Airの回転を一致させる計算をして、NRCameraRigParentのrotationに反映している点です。
こうすることで、カメラから算出したスマホの位置をNreal Airの視野の位置に変換しています。

実機実行

実機準備

Android実機側では、まずは「開発者モード(Developer mode)」に変更して、さらに「USBデバッグ」ができるようにしておきます。

実機接続

Android実機側の準備ができたらUSBにて接続します。
準備がうまくできていると、ここで「USBデバッグを開始する」のようなダイアログが表示されるので、かならず「OK」をクリックします。

Unity側設定

[Run Device]には接続した実機を選択します。
[Development Build]と[Script Debugging]にもチェックをいれておきます。

実機実行

[Build And Run]をクリックして、ビルドと実機転送、そして実行を行います。
youtube.com

.NET(旧名称.NET Core)アプリの配布方法について(勘違いしていたので)

.NET 5以降のフレームワークWindowsアプリ(以下、.NET Coreアプリ)を作成したとき、配布した実行可能ファイルが.NET Frameworkのときとは異なっている点を最近まできちんと把握していなかったので、忘備録代わりに投稿します。

.NET Coreアプリの2つの展開

.NET Coreアプリを配布する形式は2つの配置モード(展開形式)があります。
例として、hogehogeというアプリ名のアプリを配布する場合について考えてみましょう。

フレームワーク依存

フレームワークに依存するという名称から、配布先のフレームワークx86かx64かなど配布先の環境を意識しないといけないように思えますが、そうではありません。

このファイル形式の良い点は2つ

  1. 配布ファイルはx86/x64の区別がない(1つだけ例外あり)
  2. 配布するファイルに.NETランタイムは入らないのでコンパクト(配布ファイルの例:66ファイル、合計62MB)
Any CPUでビルドしたものを配布できる

配布先にあるフレームワークに動作モードが依存するので、展開形式ではx86かx64かを意識しないでビルド、つまり、Any CPUでビルドすることができます。

配布先での実行はdll名指定で

hogehogeというアプリ名の場合、配布物の中では、hogehoge.dllがアプリファイルとなりますので、

dotnet hogehoge.dll

のようにして実行します。インストーラーの中で、アプリショートカットを作成して、このコマンドを実行するように設定するなどの工夫が必要です。

実行可能ファイル

hogehoge.dll以外にもhogehoge.exeというファイルも配布されますが、配布先でのhogehoge.exeの実行には注意が必要です。
dotnet hogehoge.dll」での実行は配布先がx86環境でもx64環境でも(なんならWindows環境以外でも場合によっては)実行ができます。
しかし「hogehoge.exe」での実行は、例えば、開発環境がx64だった場合、hogehoge.exeは64bitアプリとして作成されるので実行環境がx86環境の環境に配布しても実行できません
また、開発環境がx86だった場合、hogehoge.exeは86bitアプリとして作成されるのでx64環境に配布してもx64アプリではなくx86アプリとして動作しようとするので、x86の.NET6ランタイムがないと実行できません
この赤字の部分が勘違いしていて、「なんでx86環境で動かないんだ~」と1日悩んでいました。
x64環境でビルドして、フレームワーク依存で配布した場合、x86環境での実行は「dotnet hogehoge.dll」一択です!

自己完結

配置モードとして「自己完結」を選択すると、ターゲットランタイムも含めた形で実行に必要なファイルがすべて含んでファイルが生成されます。

このファイル形式の良い点は、次の点です。

  1. 配布先の環境で、を事前にインストールする必要がない(配布ファイルの例:350ファイル、合計214MB)

その代わり、Any CPUビルド指定していたとしても、ターゲットランタイムとして「win-x64」と指定するので、作成されたファイルは、DLLも含め、Windows x64環境に依存したものになります。
もし、x86とx64の両方に配布する予定があるのであれば、x86用自己完結インストーラーとx64用自己完結インストーラーの2つのmsiファイルを作成する必要があります。

Visual Studio Installer Projectでのmsiファイル作成

Visual Studio 2022と最新のVisual Studio Installer Project Templateを使えば、.NET Coreアプリもmsiファイルとしてインストーラーファイルを作成することができます。

配置モードが「自己完結」の時のインストーラープロジェクト

配置モードを「自己完結」としてVisual Studioから「発行」したものをVisual Studio Installer Projects 拡張機能を使ってmsiファイルを作る場合は次のような手順になります。

Setupプロジェクトの新規作成

Visual Studio Installer Projects 拡張機能をインストールしておくと、新規プロジェクトタイプして「Setup」が選択できます。

インストールターゲットの指定

インストーラープロジェクトが新規作成されたら、プロジェクトのTargetPlatformプロパティを発行時に選択したプラットフォームに合わせます。今回は「win-x64」としたので、「x64」を選びます。

「項目の公開」の追加

インストーラープロジェクトが新規作成されたら、プロジェクトを右クリックして[プロジェクト出力]を選択して、「項目の公開」をプロジェクトに追加します。

PublishProfilePathの設定

「項目の公開」がプロジェクトに追加されたら、そのPublishProfilePathプロパティに「発行」で作成ししたプロファイルファイルを指定します。

もちろん、この発行プロファイルの配置モードは「自己完結」にしておきます。
これにより、発行プロファイルに基づいたビルドが行われて、そこの出力を使ってmsiファイルが作成されます。

ビルドを開始しました...

            • Starting pre-build validation for project 'HogehogeTrialSetupCore' ------
            • Pre-build validation for project 'HogehogeTrialSetupCore' completed ------

1>------ ビルド開始: プロジェクト: HogehogeTrialSetupCore, 構成: Release ------
Building file 'C:\User\Project\dotNET\HogehogeTrialSetupCore\Trial\TrialSetup.msi'...
Packaging file 'System.Windows.Forms.Design.resources.dll'...
:
(中略)
:
Packaging file 'System.Net.Http.Json.dll'...
========== ビルド: 成功 1、失敗 0、最新の状態 1、スキップ 0 ==========
=========== 経過時間 01:19.271 ==========

配置モードが「フレームワーク依存」の時のインストーラープロジェクト

配置モードを「フレームワーク依存」としてVisual Studioから「発行」したものをVisual Studio Installer Projects 拡張機能を使ってmsiファイルを作る場合は次のような手順になります。

Setupプロジェクトの新規作成

Visual Studio Installer Projects 拡張機能をインストールしておくと、新規プロジェクトタイプして「Setup」が選択できます。

インストールターゲットの指定

インストーラープロジェクトが新規作成されたら、プロジェクトのTargetPlatformプロパティを「x86」とします。
こうすることで、x64環境でもx86環境でも動作するmsiファイルが作成できます。
なお、ここでx86と指定しても、インストールされるアプリ自体がx86アプリになるわけではありません。

「項目の公開」の追加

インストーラープロジェクトが新規作成されたら、プロジェクトを右クリックして[プロジェクト出力]を選択して、「項目の公開」をプロジェクトに追加します。

PublishProfilePathの設定

「項目の公開」がプロジェクトに追加されたら、そのPublishProfilePathプロパティに「発行」で作成ししたプロファイルファイルを指定します。

もちろん、この発行プロファイルの配置モードは「フレームワーク依存」にしておきます。
これにより、発行プロファイルに基づいたビルドが行われて、そこの出力を使ってmsiファイルが作成されます。

インストールプロセスの中でランタイムをインストール(前提条件の追加)

フレームワーク依存の場合、.NETランタイムが事前にインストールされていることが必要となりますので、インストーラーの実行プロセスの中で.NETランタイムもインストールするように設定します。
ソリューションエクスプローラーでプロジェクトを右クリックしてプロパティを表示します。
[Prerequisites]ボタンをクリックします。

必要なランタイムを指定します。

ランタイムのチェックだけでインストールは事前に実施

インストーラーの中でランタイムをインストールしないときは、前提条件は追加しないようにします。

配布先でのインストール結果の確認

配置モードが「自己完結」の時のインストール結果


アプリフォルダに.NETデスクトップランタイムに含まれるファイルもインストールされて、ファイル数350個がアプリフォルダに展開されます。

配置モードが「フレームワーク依存」の時のインストール結果


アプリフォルダに.NETデスクトップランタイムのファイルはインストールされないので、ファイル数66個となります。

ARFoundationで平面検知できたのでオブジェクトを落としてみよう

前回:
hatsune.hatenablog.jp


前回は、ARFoundationを使って平面検知をするアプリを作ってみました。
この平面検知ですが、検知した結果を表示するだけではなく、RigidBody(物理機能)をつけたオブジェクトを落とせば、検知した平面と干渉して、現実の床の上でオブジェクトがとまってくれたり、ころころと床を転がったりすることができます。

それでは、前回作成した平面検知のサンプルでオブジェクトを落としてみましょう。

初期表示で1m先に立方体があるので、この立方体をタップしたらRigidBody付きの立方体が生まれて自由落下(RigidBody付きなので)して平面検知した床=実物の床の上にどんどん積みあがっていくようなものをつくります。

立方体をタップする

ARFoundationで表示しているオブジェクトをタップしたかどうかを検出するためには、タップ位置を「Ray」として取得して、そのRayの線上にあるオブジェクトが何か?という判定が必要となります。

AR Raycast Managerの追加

「AR Session Origin」に「AR Raycast Mangaer」コンポーネントを追加します。

これでタップ位置を「Ray」として取得できます。

Rayの線上のオブジェクトを判定するスクリプトを作成

[Project]に「Script」フォルダを作成して、その中に「AirTapGesture」という名前でスクリプトを作成します。
gist.github.com

Rayを取得

var ray = this.ArCamera.ScreenPointToRay(touch.position);

ARFoundationのカメラオブジェクトがArCameraに割り当てられていれば、「ScreenPointToRay(touch.positoin)」にて、タップした位置がRayとして取得できます。

Rayが当たっているオブジェクトを取得

RaycastHit hit;
var hasHit = Physics.Raycast(ray, out hit);

「Physics.Raycast」を使ってRay上にあるコライダー(オブジェクトの物理情報)の情報を取得します。
そして、RayがぶつかっているコライダーのgameObjectを取得すれば、どんなオブジェクトにRayが当たっているかが分かります。

var target = hit.collider.gameObject;

該当オブジェクトを複製して自由落下

if (target.name.Contains("Cube"))
{
var clone = Instantiate(target); // Clone
clone.AddComponent();
}

該当オブジェクトが「Cube」であった場合だけ、「Instantiate」でそのCube自身を複製して、そこの「RigidBody」を追加して自由落下および物理演算が働くようにします。

スクリプトを「AR Session Origin」に割り当て

スクリプトが作成出来たら、Assets>Scriptの「AirTapGesture」を[Hierarchy]の「AR Session Origin」にドラッグアンドドロップします。

Rayを飛ばすカメラオブジェクトの割り当て

スプリプ途中で使うカメラとして、「AR Session Origin」の子オブジェクトのカメラを指定します。

実機デバッグ

実機準備

Android実機側では、まずは「開発者モード(Developer mode)」に変更して、さらに「USBデバッグ」ができるようにしておきます。

実機接続

Android実機側の準備ができたらUSBにて接続します。
準備がうまくできていると、ここで「USBデバッグを開始する」のようなダイアログが表示されるので、かならず「OK」をクリックします。

Unity側設定

[Run Device]には接続した実機を選択します。
[Development Build]と[Script Debugging]にもチェックをいれておきます。

実機実行

[Build And Run]をクリックして、ビルドと実機転送、そして実行を行います。
youtu.be

Nreal Airを買ったので、まずはARFoudationだけ試してみる

はじめに

3DoFと6DoF

Nreal Airは3DoF(視線方向の回転や傾き検知)ができますが、Nreal Lightの6DoF
nのように「移動」を検知できません。
ですから、360°空間に配置した仮想オブジェクトがそこにあるように魅せることはできますが、そのオブジェクトに近づいたり後ろに回り込んだりのような動きは検知できません。

ARFoundationで不足分を補う

そこで、UnityにあるARFoundationを使ってスマホの位置測定および位置移動を取得してNreal Airに足りない移動検知のための+3DoFを取得して合成することでNreal Airでも6DoF的なアプリがつくれるのではないかと考えました。

まずは、ARFoundationの使い方を覚えよう

そこで、まずはARFoundationだけを使ったAndroidアプリをUnityで作成して、ARFoundationの使い方を調べてみます。

準備

開発環境

  • Unity 2021.3.15f1
  • Visual Studio 2022 (Community 2019なども可)

新規プロジェクト作成

新規作成

Unity Hubを起動して[プロジェクト]→[新規作成]をクリックして、プロジェクトの新規作成を行います。

テンプレートの指定

テンプレートとして[3D]を選択して、プロジェクト名を指定したら[作成]をクリックします。

プラットフォームの変更

Unityを起動してUnityの新規プロジェクトが作成されたら、[File]-[Build Settings]メニューから設定画面を開きます。
プラットフォームを「Android」に変更して[Switch Platform]をクリックします。

はじめてのARFoundationアプリ開発

ARFoundationパッケージの導入

Unityの[Window]-[Pakage Manager]メニューで[パッケージマネージャー]ウィンドウを開きます。

[パッケージマネージャー]ウィンドウで「Packages]の場所を「Unity Registry」に切り替えます。

そして、「AR Foundation」と「ARCore XR Plugin」を指定して、ウィンドウ右下の[Install]ボタンでインストールします。

Main Cameraの削除

「MainCamera」は不要なので「Hierarchy」から削除します。

オブジェクト追加

「Hierarchy」を右クリックして、[XR]-[AR Session]メニューをクリックしてAR Sessionを追加します。

同様に[XR]-[AR Session Origin]メニューをクリックしてAR Session Originを追加します。

AR Sessionとは

AR Sessionは、ARシーンのプロセスを管理するコンポーネントです。ARFoundationを使うときには必要なコンポーネントだくらいの理解で問題ありません。

AR Session Originとは

AR Session Originは、現実空間の情報をUnity上の「位置、方向、大きさ」に変換してくれるコンポーネントです。
AR Session Originの中には「ARCamera」オブジェクトが含まれていて、アプリが起動されたときのデバイス位置=視点位置=ARCameraの位置ということになります。
「ARCamera」は「MainCamera」とリネームしておくとよいでしょう。

平面検知の追加

ARFundationで現実空間の平面を検知するには「AR Session Origin」に「ARPlane Maneger」を追加するだけで自動的に平面検知が行えます。
「Hierarchy」で「AR Session Origin」を選択し、「Inspector」で「ARPlane Maneger」を追加します。

検知した平面に平面を表示する

「ARPlane Maneger」が検知した平面は、そのままでは人が見える形で何か表示がされるわけではありません。
そこで、検知した平面に平面を表示するように設定します。
どのような表示かは、「ARPlane Maneger」の「Plane Prefab」に指定した内容できまります。

表示用プレハブフォルダの設置

「Project」に「Prefab」フォルダを作成します。

表示オブジェクトの用意

「Hierarchy」を右クリックして、[XR]-[AR Default plane]メニューであらかじめ用意されている平面オブジェクトを追加します。

表示オブジェクトをプレハブ化

「Hierarchy」に追加された「AR Default plane」を「Project」-「Prefab」フォルダにドラッグ&ドロップしてプレハブ化します。

「Hierarchy」上の「AR Default plane」は不要なので削除しておきます。

AR Session Originに表示用プレハブを指定


Cubeの配置

[Hierarchy]で「AR Session Origin」を右クリックして[3D Object]-[Cube]メニューでCubeをARFoundationの管理下で配置します。

Positionは(0, 0, 1)、Rotationは(30, 30, 0)、Scaleは(0,2, 0.2, 0.2)として、1m先に少し回転した立方体を配置します。

Player Settingsの設定

[Fille]-[Build Settings]-[Player Settings]で設定ウィンドウを開いたら、Androidの[Other Settings]の中にある設定を変更します。

Graphics APIs から Vulkan を削除

[Graphics APIs」から「Vulkan」を削除します。

Minimum API Levelの変更

Minimum API Levelを7.0以上に変更します。

XR Plug-in Managementの設定

[Edit]-[Project Settings]で設定ウィンドウを開いたら、[XR Plug-in Management]で[ARCore]にチェックを入れてARCoreの初期化するように指定します。

実機デバッグ

実機準備

Android実機側では、まずは「開発者モード(Developer mode)」に変更して、さらに「USBデバッグ」ができるようにしておきます。

実機接続

Android実機側の準備ができたらUSBにて接続します。
準備がうまくできていると、ここで「USBデバッグを開始する」のようなダイアログが表示されるので、かならず「OK」をクリックします。

Unity側設定

[Run Device]には接続した実機を選択します。
[Development Build]と[Script Debugging]にもチェックをいれておきます。

実機実行

[Build And Run]をクリックして、ビルドと実機転送、そして実行を行います。
youtu.be