やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

Unityプロジェクトのディレクトリ構成と .gitignore

Twitterで話題に上がっていたので、自分なりのやり方を。

ディレクトリ構成

Assets/下

自分で作るものはAssets/下にディレクトリ (Folder) を作り、そこにまとめています。

  • Assets
    • MY_PROJECT_NAME
      • Scripts
      • Tests
      • とか

Editor/はMY_PROJECT_NAME/の直下だったり、MY_PROJECT_NAME/Scripts/下だったり毎回不安定*1

Assets外

主にビルドスクリプト*2で以下のように指定しています。いずれも.gitignore(後述)で除外指定されているところ。

  • ビルド成果物は Builds/
  • ログは Logs/
  • テスト結果も Logs/
  • コードカバレジ*3も Logs/

.gitignore

giboでベースを生成

.gitignoreファイルはgiboで生成したベースに、プロジェクトごとの設定を追加しています。

github.com

私はIDEにJetBrains Riderを使っているので、次のように。

$ gibo dump Unity JetBrains >> .gitignore

これで、以下2つの定義が連結された.gitignoreができます。

Rider以外のIDEを使用する場合は JetBrainsVisualStudioVisualStudioCode に置き換えます。

なお、OSごとの定義はあらかじめグローバルの.gitignoreに設定されている前提ですが、gitに不慣れなメンバーもいる状況では macOSWindows を加えてもいいでしょう。

プロジェクト固有の定義を追加

必要に応じて、.gitignoreに追加していきます。

まず極端な例。公開 or 納品するプロジェクトなど、3rd partyのアセットをすべて除外したい場合は、以下のようにMY_PROJECT_NAME以外をすべてトラックしないようにします*4

/Assets/*
!/Assets/MY_PROJECT_NAME*

なお、スラッシュを含めず*を書いているのは、ディレクトリの.metaファイルも含めるためです。

すべてではない場合、シートライセンスのエディタ拡張など、リポジトリに含めたくないものを個別に指定していきます。例えば、

/Assets/ConsolePro*

同様に、Assets/下に生成されるファイルでトラックしたくないものも追加します。代表的なものは以下。

Play Mode tests実行時に作られて、まれによく残ってしまうScene

/Assets/InitTestScene*.unity*

Build Report Inspector

/Assets/BuildReports*

VRCSDKがアップロード用にプロジェクトルートに作るファイル

/*.unitypackage

UniVRMで生成する中間ファイル

/Assets/*.vrm
/Assets/*.vrm.meta

アセット提供側が気をつけたいこと

アセット提供側としても、自身のアセットはAssets/直下に置くのでなくディレクトリを切るべきです(以下MY_ASSET_NAMEとします)。

また、再配布可能な他者のアセットを同梱する場合は、MY_ASSET_NAMEの下ではなく、オリジナルのディレクトリに置くと、他のアセットとの競合を避けられます。

アセットの設定ファイルをAssets/MY_ASSET_NAME/下に置いてパス指定で読み書きしてしまうと、ユーザがディレクトリを変更できなくなり不便です。 設定は、 Settings Manager package を使用してProjectSettings/下に保存するようにすると使いやすくなります。

*1:Editor/は、Assets/直下でなくどこにあってもEditor扱いされます

*2:Makefile老人会なのでMakefile

*3:Code Coverage packageの場合、設定で出力先を変更できます

*4:ただし、エディタ拡張だけでなくランタイムのスクリプトその他も除外するのは、納品には良いのですがCIで不便です。Gitはこの設定で、CIはignore定義が別のUnity Collaborateにするという手もあります

リモート時代のモブプログラミング(モブワーク)勉強会でmob IntelliJ pluginをお披露目 #モブLOVE #モブプロ #MobProgramming #RemoteMobProgramming

リモートモブプログラミングにフォーカスした勉強会(もちろんオンライン開催)のLT募集があったので、作っているリモートモブプロ支援IntelliJ pluginの紹介をしてきました。

moblove.connpass.com

勉強会冒頭のアンケートでは、リモートモブプロをやたことはある人は多いものの、単発であったり、うまくできていないという人が2/3くらい。

終盤の 銀の弾丸ラジオ 公開収録では寄せられたお悩み相談に、及部さんたちだけでなくZoomのチャットにも色々知見が寄せられて*1、たいへん有意義な会でした。

そんな中、オンラインあみだくじによってLTのトリで発表させていただきました。Visual Studio CodeのLive Share機能を使っている事例がいくつかあったので、JetBrains派の方々に向けてバランス取れたのではないでしょうか。

プラグインは JetBrains Plugins Repository で公開されています。

plugins.jetbrains.com

ただしまだEAP Channelのみなので、IntelliJ の Preferences | Plugins にチャネルを設定しないと出てきません。 もしくはplugin pageからファイルをダウンロードしてインストールすることも可能です。

EAP Channelの設定その他はGitHub repositoryのREADMEを参照してください。

github.com

チームの事情等でIntelliJが使えないという方は、移植元である mob コマンドをお試しください。こちらの記事でも紹介しています。 www.nowsprinting.com

はじめてのIntelliJ plugin開発でしたが、得られた知見は今後も当ブログで記事にしていく予定です。下のリンクから記事一覧が見られます。 www.nowsprinting.com

*1:Zoomのチャットは残らないのがつらいところですね

#yokohamaunity (cluster開催)で『Rider plugin の作りかた』をLTしてきました

yokohama.unity初のオンライン開催である「yokohama.unity ~オンラインDEハジメテユルクヤッテミル#0~」で、IntelliJ Rider plugin 開発についてのLTをしてきました。

f:id:nowsprinting:20200424225918p:plain

meetup.unity3d.jp

今回は初のオンライン、clusterでの開催でした。clusterはオーディエンスのリアクションが見られるのがとても良いですね*1

ただ、ものすごく贅沢を言うと、

  • 音声がやや聞き取りづらかった(うちの回線の問題だとは思いますが*2
  • スライドの登壇者ビューが小さめ(解像度低め)なので、スライドにキーワードを散りばめておいて話すスタイルだと厳しい

みたいなところは気になりました。

あと個人的に、うっかり他のアカウントにTwitterアカウントを紐付けてしまったため、cluster内で打ったコメントをTwitterに流せないのです*3。連携解除機能とか実装されてほしい。

登壇資料

以下、今回のスライドと、その中で紹介している過去記事です。

www.slideshare.net

www.nowsprinting.com

www.nowsprinting.com

www.nowsprinting.com

説明をだいぶ端折ってしまったSettings/Preferencesなど、また改めて単発のブログ記事を書き起こすつもりです。 今後の追加も含め、下のリンクから記事一覧が見られます。

www.nowsprinting.com

また、製作途中なものを晒したIntelliJ プラグインは、次のイベントでお披露目できる見込み…?

moblove.connpass.com

[5/18追記] 無事リリースされました!

plugins.jetbrains.com

懇親会

懇親会はRemoでという話だったのですが、重すぎてつながらず、急遽Zoomへ。 人数少なくなってしまった寂しさと、少人数だからZoomで会話が成立したので結果オーライ感と。

トータルで楽しかったので、ぜひまたやりましょう!

関連

仮面ライダーゼロワン RKF 仮面ライダーランペイジバルカン

仮面ライダーゼロワン RKF 仮面ライダーランペイジバルカン

  • 発売日: 2020/04/25
  • メディア: おもちゃ&ホビー

*1:なぜ壇上からのスクショを撮っていないのか…

*2:自分の音声どうだったのだろう、というのは気になるので教えてほしいです

*3:ZoomやDiscordのテキストチャットで盛り上げることもできますが、ログがそのサービスに閉じてしまいます。その点、clusterはコメントをTwitterにも流せるのが良いところなのですが

IntelliJ plugin から他のプラグインを使用する

IntelliJ (JetBrains IDE) ファミリー向けのプラグイン開発において、他のプラグイン(例えばGitを操作するための Git4Idea *1 など)や、Riderなど言語別IDEの機能を使う設定について。

基本的なことは公式ドキュメントの下記ページに載っており、それに沿って補足していきます。

プラグイン依存関係 / IntelliJ プラットフォーム SDK プラグイン開発ガイド

build.gradle

build.gradleの intellij ブロック内に plugins の設定を追加します。

Git4Ideaを使用する例 (Kotlin) :

intellij {
  version = "2020.1"
  setPlugins("git4idea")
}

Gradleでビルドおよび runIde タスクを実行するとき、この設定が使われます。 このとき、ここで記述したプラグインの依存関係については自動的に解決されます。

しかし、 test タスクでユニットテストを実行するときは、プラグインの依存関係が解決されないという制限があります。 上例の git4idea には依存先がないのですが、例えば android を使用する場合は次のように android が依存するすべてのプラグインを書く必要があります。

intellij {
  version = "2020.1"
  setPlugins("android", "junit", "Groovy", "gradle")
}

詳しくは下記 Issue を参照してください。この問題が修正される気配は無さそうに見えます。

Install plugin dependencies transitive dependencies automatically for tests. · Issue #38 · JetBrains/gradle-intellij-plugin · GitHub

plugin.xml

plugin.xml には <depends> で依存するプラグインを宣言する必要があります。 com.intellij.modules.platform の下に追加していきましょう。

<depends>com.intellij.modules.platform</depends>
<depends>Git4Idea</depends>

これはランタイムで使用される設定です。ここに書く名称についてはコード補完が効きます。

なお、プラグインの依存を必須にしない場合、 <depends>optional 属性を指定できます。 これは試していないので、公式ドキュメントを参照してください。

classpath

以上でプラグインのビルド・配布はできるのですが、IntelliJ IDEA上で開発を進めるにはclasspathも設定する必要があります。

File > Project Structure... を開き、SDKs > 11(使用しているJDKバージョンによりますが、ここではAmazon Corretto 11)を選択、classpathタブの"+"クリックで必要なjarファイルを選択します。

f:id:nowsprinting:20200419195750p:plain

jarファイルは、IntelliJ IDEAインストールディレクトリ/plugins/下にあります。 Git4Ideaの場合、plugins/git4idea/lib/下に4つのjarファイルがありますが、ディレクトリごと選択すれば大丈夫です*2

参考

プラグイン開発に関しては、公式ドキュメントにある程度の情報が載っています。日本語版もちゃんと更新されています*3

IntelliJ プラットフォーム SDK / IntelliJ プラットフォーム SDK プラグイン開発ガイド

IntelliJ Platform SDK / IntelliJ Platform SDK DevGuide

少し込み入った話になると、ヘルプセンターがヒットしたりはします。

IDEs Support (IntelliJ Platform) | JetBrains

本稿のclasspathの件はここにありました。

How to build and use git4idea as a library in plugin – IDEs Support (IntelliJ Platform) | JetBrains

*1:Git4Ideaはビルトインされているのでインストール不要なプラグインですが、プラグインから使用するための設定は必要です

*2:はじめgit4idea.jarだけを選択していたところ、中途半端な解決しかされず悩みました…

*3:が、翻訳には限界があるので検索で探し当てるのは難しいです

IntelliJ plugin からのログ出力

IntelliJ (JetBrains IDE) ファミリー向けのプラグイン開発をしていて、ログ出力まわりが少々わかりにくかった*1のでメモ。

プラグインからのログ出力

プラグインからログを出力するには、 com.intellij.openapi.diagnostic.Logger を使います。

Javaの場合

Logger log = Logger.getInstance(getClass());
log.trace("trace!!!");
log.debug("debug!!!");
log.info("info!!!");
log.warn("warn!!!");
log.error("error!!!");
log.error("例外を渡すことも可能", new Throwable());

Kotlinの場合*2

val log = Logger.getInstance(javaClass)
log.trace("trace!!!")
log.debug("debug!!!")
log.info("info!!!")
log.warn("warn!!!")
log.error("error!!!")
log.error("例外を渡すことも可能", Throwable())

サンドボックス実行環境のログ出力先

Gradle > runIde で実行すると起動するサンドボックスでは、ログはプロジェクトのルートディレクトリ下 /build/idea-sandbox/system/log/idea.log に出力されます。

idea.logは、Runウィンドウで見られるようにしておくと便利です。 Run > Edit Configurations... を開き、Gradle > runIde の"Logs"タブで"+"アイコンをクリックしてidea.logのパスを追加します。

f:id:nowsprinting:20200418183403p:plain

すると、Runウィンドウにタブが追加されるようになり、そこで idea.log を確認できます。

f:id:nowsprinting:20200419094611p:plain

なお、タブの右方にあるテキストフィールドでログの絞り込み、その左隣のドロップダウン(上図では"all")で表示するログレベルの変更ができます。

実際のログ出力先

プラグインをビルドした後、正規のルートでIntelliJ IDEAなどにインストールして使用するとき、ログはmacOSでは ~/Library/Logs/JetBrains/IntelliJIdea2020.1/idea.log に出力されます。

IDEをJetBrains TOOLBOXからインストールしていれば、TOOLBOXを開いて目的のIDEの右の六角形 > Settings にある "Show logs directory" ボタンで idea.log の場所がFinderで開きます。

なお、2020.1から、ログだけでなく、設定、キャッシュ、プラグインの格納場所が変更になっています。 2019.3以前の情報も含めてまとめられたページを教えていただきました。

ログレベルの変更

Diagnostic loggerのログ出力レベルのデフォルトは INFO です。 DEBUG まで出力するには、 Help > Diagnostic Tools > Debug Log Settings… を開き、改行区切りで # + パッケージ名もしくはクラスのFQCNを設定します*3

f:id:nowsprinting:20200418190423p:plain

ダイアログに書いてあるとおり、TRACE まで出力するにはパッケージ名もしくはFQCNの後ろに :trace を付けます。

なお、いずれも、開発中のサンドボックス実行環境の場合、runIdeで起動された側(サンドボックス側)のIDEで設定する必要があります。

参考

プラグイン開発に関しては、公式ドキュメントにある程度の情報が載っています。日本語版もちゃんと更新されています*4

IntelliJ プラットフォーム SDK / IntelliJ プラットフォーム SDK プラグイン開発ガイド

IntelliJ Platform SDK / IntelliJ Platform SDK DevGuide

少し込み入った話になると、ヘルプセンターがヒットしたりはします。

IDEs Support (IntelliJ Platform) | JetBrains

*1:バージョンの変わり目にはじめてのプラグイン開発をしたからというのが最大の理由ですが

*2:KotlinのパッケージレベルでjavaClassの代替手段がほしい。どなたか知っていたら教えて下さい

*3:ワイルドカードではないので、特定のパッケージ以下をすべて有効にしたければ画像のように書けばok。後ろに*をつけると無効になります

*4:が、翻訳には限界があるので検索で探し当てるのは難しいです

リモートワークでコミュニケーションが足りないなら、モブプロすればいいじゃない

リモートワークが急激に広まる中、その利点とともに、チームのコミュニケーションが不足しがちという不安も聞こえてきます。 その対策としての、リモートモブプログラミングのススメです。

普段の職場へのモブプログラミングの導入には色々と障壁もありますが*1、急なリモートシフトの混乱に乗じてを円滑に進める施策のひとつとして試してみる価値はあるのではないでしょうか。

モブプログラミングとは

まず、モブプログラミング(以下モブプロ)について。知ってる方は飛ばしてください。

モブプロとは、プログラミングを

  • 同じ仕事を
  • 同じ時間に
  • 同じ場所で
  • 同じコンピューターで

行なうことです。

コンピューターを操作するタイピスト*2は交代制で、その場の全員で目の前の問題解決に取り組みます。 ナビゲーターは決してオブザーバーや傍観者ではなく、それぞれ考え、検索し、話し合い、決定します。むしろタイピストは入力するだけなので、言語やドメイン知識があまりないメンバーでもこなせます。

なお、モブ「プログラミング」と銘打たれてはいますが、プログラミングに限らず様々な作業をモブで行なう事例も聞いています*3
また、普段プログラミングを主としていないテストエンジニアやプランナーがプログラマのモブに混ざって知識を共有しつつ作業を進める事例も聞きます。

より詳しく、また、うまく始めるためのコツなど、次のスライドをぜひ参照してください。

speakerdeck.com

実際にやってみて実感しているのは以下のような点です。

  • 暗黙知暗黙知のまま共有できる情報量
  • 知識は、必要なときにタイムリーにインプットするほうが吸収できる
  • プログラミングでは調査の時間がそれなりにあるが、それを手分けできる(もしくは誰かが知っている)ので意外と効率は悪くない
  • 探索的なコードリーディングでも、迷子になりにくい
  • 従来、PRレビューで指摘したりしなかったりすることを、ストレスなくコードに反映できる

リモートモププログラミング

モブプロの定義のうち「同じ場所で」をオンラインで実現するのがリモートモブプロです。

リモートで行なうメリットとして、オンサイトにおける以下の問題が解消します。

  • オフィスに場所がない(会議室が空いていない、自席でやると近所迷惑、大きいモニタが無い)
  • メンバー間でキーボードやエディタの差異があり「同じコンピューターで」コードを書くストレス

以下、自分の体験と、Remote Mob Programming | How we do Remote Mob Programming. および How Remote Mob Programming Is Working for Me を加味したおすすめのセットアップを紹介します。

画面共有

開発環境は参加者個々のものを使い、ビデオ会議システムの画面共有 (screen sharing) 機能でタイピストの画面を全員にシェアします。

いくつか試した範囲では、Zoom Proアカウントがあれば*4Zoomが最もおすすめできますが、Google HangoutsやDiscordでも代用可能です。

ポイントは、

  • 上に挙げたサービスでは、画面共有はビデオ会議セッションのオーナーに限らず任意の参加者が開始できます。ビデオ会議セッションは1つを維持したままで大丈夫です
  • ウィンドウ単位での共有でなく、ディスプレイ1つを指定して共有すべきです。ビルド・実行などでエディタとは別ウィンドウを使用する際に、その内容もモブに対してシェアするためです
  • VSCode Live Shareなど、IDEのコラボレーション機能は(現時点では)モブプロには不向きです。表示するエディタタブおよびスクロール位置を共有できないため、みんなバラバラの箇所を見てしまい、また各自好きに編集できるため、モブとしてディスカッションするのを放棄して個々のアイデアでコードを書いてしまいがち
  • Zoomのリモートコントロール (remote control) 機能を使って1台のコンピューターの操作権をタイピストに渡す方法もありますが、ラグがコーディングの妨げになるため推奨しません。ラグが気にならない作業でなら検討の余地はありそうです

また、モブプロでは参加者すべてが仕事に集中し、貢献することを求めます。特にリモートでは内職しないように、 Remote Mob Programming | How we do Remote Mob Programming. では常に全員のカメラをonにすることを推奨されています。
しかし、慣れているチームや少人数であれば、帯域を節約するためにもカメラoffでも問題ないでしょう。その代わり、マイクは全員常にミュートにせず、相づちは声に出すよう心がけます。

タイピストの交代契機

Remote Mob Programming | How we do Remote Mob Programming. では10分インターバルを提案されています。

慣れてくれば時間制でなく、キリの良いところやタスクボードを用意して短時間で終わるチケットに区切っていく方法でも良いのですが、はじめは時間制が安心です。 休憩タイミングの設定も「n巡したら休憩」と決めやすくなります*5

オンサイトと違いタイピスト交代のコストがかかりますので、いずれにせよ時間は長めに設定するのが良さそうです。

Gitリポジトリによる受け渡し

Remote Mob Programming | How we do Remote Mob Programming. では、タイピストの交代ごとにWIPコミットをGitのリモートリポジトリ(モブセッションのブランチ)にpushし、次のタイピストがpullして続きの作業を行なう方法が紹介されています。

また、その操作をすばやく行なうためのコマンドラインツール mob が公開されています。これはGo言語製のコマンドラインツールで、次のように使用します。

$ mob start 10

これでブランチmob-sessionが作られ、その中でコードを書いていきます。"10"は交代までの時間指定(分)で、通知とデフォルトではsayコマンドの音声で交代を教えてくれます(macOSの場合)。

時間が来たら、

$ mob next

で作業状態をコミット(コミットメッセージはmob next [ci-skip])、pushしてくれます。

次のタイピストは自分のコンソールで

$ mob start 10

を実行すると、ブランチmob-sessionをpullしてくれるので続きの作業ができます。これを繰り返して進めていきます。

一連の作業が終わったら、

$ mob done

でブランチの作業内容がスカッシュされます*6。 適切なメッセージを付けてコミット、pushすることで完了です。

なお、mobコマンドの利用にあたっては、いくつか注意点があります。

  • リモートブランチ名は環境変数で設定します。1つのリポジトリで複数モブが作業する場合、モブごとに設定しましょう
  • リモートブランチをupstreamに設定しておく必要があります
  • mob done 実行時点でリモートブランチが消えてしまうのでオペレーション注意
  • mob start コマンドに share オプションを追加することでZoomの画面共有を開始(切り替え)できますが*7、あらかじめ以下の設定が必要です
    • Zoom > 設定 > キーボードショートカットを開き、「画面共有の開始/停止」の「グローバルショートカットを有効化」チェックボックスをonにします
    • macOS Catalinaの場合、スクリプトからの操作に制限がかかっています。システム環境設定 > セキュリティとプライバシー > "プライバシー"タブ > "アクセシビリティ" を開き、「下のアプリケーションにコンピュータの制御を許可」に /usr/bin/osascript を追加します*8。ただし、悪意のあるスクリプトによる操作も受け入れてしまう設定のため注意が必要です (4/6追記)

mobコマンドを使わない場合でも、交代をスムーズに行なうため「交代時のコミットメッセージにはこだわらない」「後でスカッシュする」等、ルール化しておくとよいでしょう。

[5/18追記] mobコマンドをIntelliJ pluginに移植したものをリリースしました。IntelliJ IDEsユーザの方はぜひ使ってみてください! plugins.jetbrains.com

マイク

環境音やエコーを防ぐため、外付けのマイクの使用を推奨します。指向性のあるコンデンサマイク(数千円のもので十分)で自分の声のみ拾うようにするだけで、ハウリングやタイプ音がなくなります。

私が使っているのはこれ

もしくは、スピーカーでなくヘッドホンを使用するだけでもハウリングは防げます。 ノイズフィルタリングしてくれるソフトウェアもありますが*9、音声品質はストレスの無いモブプロのために重要ですので、ハードウェアで何らかの対策をしておくことをおすすめします。

ホワイトボード

設計についてディスカッションする際は、オンラインで共有できるホワイトボードがあると便利です。 我々もまだ選定中なのですが、Miroは評判もよいですし、タスクボードやテキスト入力もできてこれひとつあれば大丈夫そうな感触です。

miro.com

描くだけであれば、ZoomやMicrosoft Teamsのホワイトボード機能や、Google JamboardやMagicalDrawといった選択肢もあります。 プログラマーは、ペンタブレットや液晶タブレットよりiPadAndroidタブレット端末の所有率が高いと思いますので、iOS/Android対応しているサービスがよいでしょう。

gsuite.google.co.jp

draw.kuku.lu

タスクボードは、GitHub ProjectsやGitKraken Glo Boardsなどの選択肢もあります。

GitKrakenの利用はぜひこちらから! www.gitkraken.com

まとめ

もちろんモブプロは万能ではなく、分担作業が向いているものもたくさんあります。しかし、全くやらないのはもったいないことだと思うので、今この状況を好機だと思って、試してみてはいかがでしょうか。

モブプロ自体、チームによって様々なやり方がありますが、最初は少々やりにくさを感じても今回紹介したようなテンプレートに沿ってやってみることをおすすめします。

参考資料

speakerdeck.com

speakerdeck.com

takaking22.com

(4/4追記) piyolog.hatenadiary.jp

*1:上司の説得(生産性が下がるのではないか等)、会議室が空いていない、自席でやると近所迷惑、大きいモニタが無い、キーボードやエディタの差異など

*2:ペアプロにおける「ドライバー」ですが、モブでは「タイピスト」のほうがふさわしいと思うのでこの表現で

*3:「モブワーク」「モブデザイン」「モブテスティング」などで検索してみてください。ただし万能ではなく、作業によって向き不向きはあります

*4:Proアカウント以上でないと40分制限があります

*5:意識的に休憩を入れないと、つい連続でやってしまって疲労困憊します(しました)

*6:この時点でリモートブランチも削除されますので注意!

*7:macOSLinuxのみ

*8:あらかじめFinderの 移動 > フォルダへ移動 で /usr/bin に移動し、サイドバーにドラッグ&ドロップして追加しておくことで指定可能になります

*9:https://krisp.ai/ など

UWA GOTでUnityアプリのプロファイリング(iOS編)

Unity向けプロファイリングツールであるUWA GOTのv2.0.1から、iOSプラットフォームでのプロファイリングも可能になりました*1。 本記事では、iOS版の導入手順(Androidとの差分)と注意点などを紹介します。

なお、UWA GOTの概要については、過去記事を参照してください。

www.nowsprinting.com

www.nowsprinting.com

SDKインテグレーション

基本的なインテグレーションはAndroidと同様です。 ただし、最初に開くSceneのヒエラルキには、UWA/Prefabs/UWA_Launcherを追加します*2

以上設定したら、Development Buildを有効にしてビルドします(Xcodeプロジェクトを生成します)。

Bitcodeを無効化

XcodeプロジェクトはデフォルトでBitcodeが有効な設定になっていますが、UWA GOTのiOSライブラリはBitcodeに対応していません*3。 そのため、Build Settings > Project*4 > Build Options にある"Enable Bitcode"を探して"NO"に設定する必要があります(下図参照)。

f:id:nowsprinting:20200222224220p:plain

なお、ビルドごとに毎回手作業で修正するのはつらいので、Unityビルドの後処理でXcodeプロジェクトの"Enable Bitcode"を"NO"に書き換えるスクリプトを入れておくと便利です。

以下のコードをEditorディレクトリ下に配置します。このコードは、Unity 2019.3.2f1 + Xcode 11.1で動作を確認しています。

public class DisableBitcode : IPostprocessBuildWithReport
{
    public int callbackOrder => 0;

    public void OnPostprocessBuild(BuildReport report)
    {
        if (report.summary.platform == BuildTarget.iOS)
        {
            var path = report.summary.outputPath;
            var pbxProjectPath = PBXProject.GetPBXProjectPath(path);
            var replaceProject = new PBXProject();
            replaceProject.ReadFromString(File.ReadAllText(pbxProjectPath));

            var target = replaceProject.GetUnityFrameworkTargetGuid();
            replaceProject.SetBuildProperty(target, "ENABLE_BITCODE", "NO");

            File.WriteAllText(pbxProjectPath, replaceProject.WriteToString());
        }
    }
}

スクリプトは、下記ブログ記事を参考にさせていただきました。

blog.naichilab.com

計測

UWA GOTをバンドルしたアプリを起動すると、下図のGUIがオーバーレイされます。

f:id:nowsprinting:20200222224757p:plain

"Direct Mode"は、onにするとアプリが終了し、再起動するところから計測を開始できます。offのときは、"Overview", "Assets"いずれかをタップしたタイミングで計測を開始します。

計測が開始されると"Stop"ボタンが表示されるので、一通り動作させたらこれをタップして計測を終了します。 一度計測を行ったら、アプリを再起動しなければ次の(他の)計測はできません*5

f:id:nowsprinting:20200222224804p:plain

計測データのアップロード

Android版と異なり、計測が終了するとデータをアップロードするためのダイアログが表示されます。

f:id:nowsprinting:20200222225228p:plain

UWAオンライン(IDとパスワード入力が必要)、もしくはローカルサーバ(IPアドレスの入力が必要*6)を選択し、[データ提出]をタップします。

Onlineの場合、スクリーンショットをUWAオンラインサーバに送信するかを指定するトグルが表示されます*7。[確認]をタップすると計測データが送信されます。

f:id:nowsprinting:20200222225236p:plain

計測データの表示

以降は、Android版と同様です(ただしMonoプロファイルはありません)。過去記事およびマニュアルを参照してください。

*1:本稿執筆時点ではv2.0.2がリリースされており、本稿はv2.0.2ベースで書いています

*2:v2.0.1まではプラットフォームごとに別ファイルでしたが、v2.0.2から統一されました

*3:UWAに修正要望を出しています

*4:ProjectでなくUnityFrameworkだけでよさそうですが、スクショ撮りなおすのが面倒だったのでここままで…

*5:改善要望はしており、修正予定はあるそうです

*6:Unityエディタ上でGOT Editorを開き、WIFIボタンをクリックすると起動します。IPアドレスとポート番号が表示されますがポート番号は入力不要です

*7:Direct Modeもそうなのですが、トグルon/offがとても視認しづらいです。要望は上げています…