はじめに
こんにちは、EDMO (Engineering & Design Management Office) でUnityパッケージ開発や横断的なプロジェクトのサポートを担当しているエンジニアの井上です。
ワンダープラネットではプロダクト側で車輪の再開発が起こらないように、以下の図のように各機能に特化したパッケージをそれぞれ開発し、Unity Package Manager (以下 UPM ) の仕組みを使い各プロダクトへ提供しています。
この UPM の記事のシリーズでは Git URLでのパッケージ管理、 Scoped Registriesや Git Dependency Resolverといった高度なパッケージ管理の仕組みを今後解説する予定です。
今回は、高度な仕組みを理解する前に必要となる、基礎的な知識を解説したいと思います。UPMを更に活用したいと考えているチームリーダーの方や個人開発者の方は是非ご覧ください。
Unity Package Manager (UPM) とは
Unity公式ドキュメントによると UPMは以下のように解説されています。
パッケージは、Package Manager を通して Unity にさまざまな拡張機能を提供します。これらのパッケージを見つけ使用するために、Package Manager ウィンドウは “機能セット” と呼ばれる、一緒に使用できるパッケージのコレクションを提供します。
Unityドキュメントより抜粋
つまりUPMとはパッケージ間の「依存」をいい感じに解決してくれる仕組みです。例えばパッケージAがパッケージBを利用して開発されていた場合、パッケージAはパッケージBに依存していることになります。UnityプロジェクトにパッケージAを追加すると依存しているパッケージBも自動的に追加してくれるのが UPMの仕組みというわけです。
パッケージ間の依存解決の仕組み
今回は、Unityプロジェクトで Unity公式パッケージの 「Streaming Image Sequence」というパッケージ を使えるようにしてみます。その中で、パッケージ間の依存がどのように解決されるのかを見ていきましょう。
ちなみにStreaming Image SequenceはUnity UIとUnity Timelineの2つのパッケージに依存しています。つまり。本来は、本体のパッケージのとは別に同時に二つのパッケージもインストールする必要があります。
依存解決の流れの全体像を図示すると以下のようになります。以降で順を追って説明します。
まず、UnityプロジェクトのPackagesディレクトリ以下のmanifest.jsonに以下を記述します(通常のパッケージ追加手順においては、UnityのPackage Manager UIからでもOKです)。
{
"dependencies": {
"com.unity.streaming-image-sequence": "0.3.0-preview"
}
}
manifest.jsonを保存してUnityエディターに戻るとパッケージのインポートが始まるかと思います。インポートの処理の裏ではパッケージの依存解決が行われています。
今回のパッケージ名はcom.unity.streaming-image-sequenceと記述されており、com.unityで始まっています。com.unityが記述されているのでUnityエディターはUnityのレジストリに接続しstreaming-image-sequenceが何なのかを解決しようとします。
解決した結果、 streaming-image-sequenceをダウンロード、Unityプロジェクトにインポートし以下のディレクトリにキャッシュします。
Library/PackageCache/com.unity.streaming-image-sequence@0.3.0-preview
ここで、上記のディレクトリ の中身を覗いてみると、Packages以下に同様にpackage.jsonファイルがあることが分かります。これはStreaming Image Sequencerパッケージの依存ライブラリの定義で、Unity UIパッケージとTimelineパッケージが必要であることが記載されています。
{
"dependencies": {
"com.unity.unity-ui": "1.0.0",
"com.unity.timeline": "1.2.14"
}
}
そして、UPMはこの定義に従い、再びUnity のレジストリに接続し今度はUnity UIとTimeline のパッケージをそれぞれダウンロードして、同じように以下のディレクトリにキャッシュします。
Library/PackageCache/com.unity.unity-ui@1.0.0
Library/PackageCache/com.unity.timeline@1.2.14
Unity UIや Timelineのパッケージのpackage.jsonのdependenciesの項目は以下のように空なっており、ここでようやく必要な依存ライブラリが他にないということが判明するため、依存解決の処理が完了します。
{
"dependencies": {}
}
UPM依存解決の課題
上記のようにパッケージ間の依存解決というパッケージ管理の仕組みはとても便利です。あるパッケージが複数の他パッケージを利用して開発されている場合でも、利用したいUnityパッケージだけを直接指定するだけですぐに利用可能になります。また複数のパッケージが同じライブラリを共有している場合などもうまく管理してくれます。
しかし、この依存解決によりパッケージ取得はNode Package Manager系のレジストリサーバーでしか利用できません。たとえば、Unity公式のレジストリや、有志にて運営されているOpenUPMへの登録、もしくは自前でのサーバー構築などが必要です。
つまり、自前のパッケージやライブラリなどをGitなどで管理している場合、この依存解決の仕組みは単純には利用できません。UPMはGitリポジトリのURLも指定することができますが、あくまで指定したリポジトリのみのインポートしか働かないためです。パッケージやライブラリを設計上の都合で複数コンポーネントに分割している場合などに、この制限がネックになります。かといってGitリポジトリ上で活発に開発している場合、微修正のためにいちいちレジストリ登録するのも現実的ではありません。
まとめ
今回は Unity公式パッケージの「パッケージ間の依存解決の仕組み」と、その上で独自パッケージを開発・管理する際にネックになり得る点について解説しました。
今後、別の記事ではワンダープラネットで、これらの課題をどのように解決しているかについて解説できればと思います。
今回の記事で少しでも UPMや高度なパッケージ管理の仕組みを理解する上での手助けになれば幸いです。
参考資料
- 解決と競合 (Unity ドキュメント)