1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Unity x LeapMotionでもAssemblyDefinitionFilesを使いたい

Last updated at Posted at 2020-05-15

Leap Motion

Leap Motionは独自のセンサとカメラ技術により、人の手をセンシングするデバイスです。
安価で入手しやすいハンドトラッキングツールとして、発売から5年以上たった今でも人気のデバイスです。

image.png

Leap Motion リープモーションLM-C01-JP : yodobashi.com(現在は取り扱いなし)

SDK

Leap Motionを使った開発をする上で、以前は公式サイトから開発環境に応じたSDKを入手する必要があったようですが、現在はGitHubからダウンロードすることが出来ます。

UnityのSDKも4.5.0が最近アップデートされるなど、VRなどの用途からかまだまだ開発が続いていきそうです。

Assembly Definition

さて、Unityにはディレクトリ単位でAssemblyを分ける機能があり、ビルド時間短縮などのために自分のプロジェクトと3rdのライブラリのAssemblyを分けるために、Assembly Definition File(asmdef)を定義することがよく行われます。

上の記事でも

ライブラリや、スクリプトを含んだアセットを公開する場合はadfを定義してアセンブリを分割するべきです。
むしろやってくださいおねがいします。

とあるように、開発者がUnity向けにライブラリ開発を行う場合はAssembly Definitionを考慮して開発することが望まれます。しかし、LeapMotionのUnity向けライブラリには2020/5/16日時点で

Assembly Definition Fileは定義されていません。

Assembly Definition Fileは定義されていません。

😇

無いとどうなる

無くても問題ないでしょ?というのはもちろんそうです。LeapMotionの中の人たちもこのスタンスなのでしょう。
しかし、すでにAssembly Definitionを持った自分のプロジェクトにLeapMotionのSDKを突っ込みたくなった時問題になります。具体的には

  • LeapMotionの定義を使用するAssemblyのディレクトリ内部でSDKを展開する
    • つまり自プロジェクトと同じAssemblyに含めてしまう
  • 自分でSDKのAssembly Definitionを設定する

の二択を迫られます。前者の場合で回避できるなら良いですが、Assembly Definitionの利点を殺しています。また、今後LeapMotionを必要とするAssemblyすべてに配置する必要が出てきます。

自分で定義

私が定義したAssembly DefinitionをGitHubに公開しています。

使ってみたい方は ここからunitypackageをダウンロード し、自分のUnityプロジェクトにimportしてください。

UnityModules-4.5.0のデフォルトからディレクトリ構成を変えていなければ、そもまま同じディレクトリに.asmdefが配置されます。

余談ですが、UniVRMでは.asmdefのみのunitypackageを分けてリリースしているようです

注意

  • 現状 4.5.0 の Core.unitypackage にしか対応していません。
  • 将来LeapMotionが正式にAssembly Definitionに対応した場合、間違いなく競合します。

***

ここで「それでは良いLeapMotion+Assembly Definitionライフを」で終わってもよいですが、折角なので苦労話も載せておきます。

苦労話

さて、新しくAssembly Definitionを追加する場合、まず何をするでしょうか?
そう、とりあえず右クリックで[Create]->[Assembly Definition]から.asmdefを作りますね。

では、UnityModules-4.5.0の Assets/Plugins/LeapMotion/Core にLeapMotion.Core.asmdefを作ってみましょう。何が起こるでしょうか?ちなみにUnity のバージョンは2019.3.12です。

image.png

正解は603件のコンパイルエラーでした。

why?

LeapMotionは殊勝なことにSDKのテストをしっかり実装しており、テストコードもunitypackageに含めています。しかし、LeapMotion.Core.asmdefにて独自のAssemblyを定義したことにより、NUnit などのテストのための定義が Assets/Plugins/LeapMotion/Core/ から参照できなくなってしまったのが原因です。
すべての定義が Assembly-CSharp にある状態なら問題にならなかったのですが、Assembly Definitionにて Assets/Plugins/LeapMotion/Core 以下のディレクトリが独立したAssemblyになったため、NUnit など必要な定義を参照できる設定を.asmdefにしてやる必要があります。

how?

LeapMotion.Core.asmdefの設定だけを良い感じにすればよいのでしょうか?

答えは No です。

全ての Tests/ のディレクトリにテスト用のAssembly Definition設定をする必要があります。

しかもこれ、以前(Unity2018.x)ではチェックボックスで切り替えれたのですが、2019.2からなくなりました。

[Create]->[Testing]->[Tests Assembly Folder]で作ることはできますが、いくつもあるLeapMotionの Tests/ ディレクトリ全てにはとてもやってられません。

Unityの仕様上.asmdefが追加される度にコンパイルが走ってハングするので尚更です。

全ての Editor/ ディレクトリの.asmdefに platfrom=Editor を定義してやる必要があります。

Assembly Definition無しなら Editor/ という名のディレクトリは自動でEditor専用のディレクトリとして認識されますが、Assembly Definitionを追加した場合、Editor/ 内に platfrom=Editor になるように自分で.asmdefを設定しなくてはなりません。

なぜ[Create]->[Editor Assembly Definition]のような操作がないのでしょうね。こちらも1つ設定するたびにUnityがハングするのでとても手作業ではやってられません。

余談ですが、おそらく最短の platfrom=Editor 手動設定順は

  • [Any Platformのチェックを外す]
  • [Deselect all]
  • [Editorのチェックを入れる]
  • [Apply]

だと思います。

これキツくね?

私も手間がリターンに合わないと判断して一度は諦めました。しかし、できそうな手順を思いついたのでやってみました。キツかったですが詰んではなかったです。

.asmdefの自動生成

人間の温かみのある手作業で.asmdefを追加していくと毎回Unityがハングするので、Unityに気づかれないように.asmdefを一括で追加します。

LeapMotion/Core/ 以下にある Editor/Tests/ という名前のディレクトリを発見し、ディレクトリのパスに応じた名前の.asmdefを自動生成するエディタ拡張を実装しました。

例えば、 LeapMotion/Core/Scripts/Animation/Editor/ のディレクトリには LeapMotion.Core.Scripts.Animation.Editor.asmdef というAssembly Definition Fileが生成されます。

.asmdefの一括参照設定

.asmdefを追加しただけでは参照の設定がないのでコンパイルエラーは直りません。
人間の温かみのある手作業で.asmdefを一つ一つ編集するとそのたびにUnityがハングするので、LeapMotionとは別の個人開発でAssembly Definition Fileを同時に編集するエディタ拡張を作っていたので活用しました。

とはいえ、内部の依存関係はSDK開発者でない私にはわからないので、取り合えずは全ての.asmdefに LeapMotion.Core.asmdef への参照を追加し、以降はエラー内容を確認して対応しました。

流石はLeapMotion、Assembly Definitionこそ無かったものの破綻した依存関係にはなっておらず、苦労はしましたが.asmdefの設定に無事成功しました。これからは FrameImage クラスを使いたいAssemblyにだけ LeapMotion.Core.asmdef の参照を追加すればよいのです。

おわりに

UnityのAssembly Definitionは便利で強力なのでもっと広く使われてほしいのですが、今回のようなややこしい問題に直面するとなると、正直まだ難しいのかなと思ってしまいます。

しかし、ライブラリ作成者は別です。Scriptを含む場合は是非Assembly Definitionを設定してください。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?