こんにちは
弊社では最近、Unityの自社製ライブラリを管理する方法として
プライベートレジストリサーバーをUnityPackageManagerで利用する方法を採用しました。
今回は採用に至る経緯や具体的な構築方法の話になります。
目次
これまでのパッケージ管理
社内で複数のUnityプロジェクトが進行していると、シーン制御やアセットバンドルの管理など
各プロジェクトで共通で扱いたい処理を所謂共通基盤として開発していくことが多いと思います。
その際に開発した基盤ライブラリを各プロジェクトに導入する方法としては
.unitypackageファイルをエクスポートしてプロジェクトに配布する方法が一般的だと思いますが、
バージョン管理の煩わしさや、基盤ライブラリ同士の依存関係を管理することの難しさ、
それにプロジェクト側でライブラリの中身を容易に書き換えられてしまう等の問題がありました。
モダンなパッケージ管理?
Unity2018からライブラリを管理する方法としてUnityPackageManagerなるものが導入され、
Unity公式のライブラリに関しては導入とバージョン管理が簡単にできるようになりました。

このUnityPackageManager、公式のライブラリと書きましたが実は自作のライブラリもパッケージとして管理することが可能で、
- パッケージ化したライブラリのGithubリポジトリのURLを指定する
- パッケージ化したライブラリのディレクトリを相対パスで指定する
という二種類の方法で自作ライブラリをパッケージとしてプロジェクトにインストールすることが出来ます(パッケージ化する方法については後述します)。
ですがこの方法は、下記の理由でプロジェクトで本格運用するのは難しいです。
- リポジトリで管理する場合リポジトリごとパッケージ化する必要がある
- ローカルファイルで管理する場合バージョン管理が出来ない
- パッケージの依存関係を管理することが出来ない
そこでタイトルの話に戻るわけですが、
UnityPackageManagerはnpm(Node.jsのパッケージを管理する仕組み)がベースになっているので、
自前でnpmレジストリサーバー(パッケージをホスティングするサービスを持ったサーバー)を立ててあげれば
公式ライブラリと同じように自作ライブラリをパッケージ管理することが可能になるわけです。
立てる
Node.jsを事前にインストールしておく必要があります。
1 Verdaccioのインストール
npmでVerdaccio(無料のnpmレジストリサーバー)をインストールします
|
1 |
$ npm install -g verdaccio |
インストールしたら下記コマンドでVerdaccioを実行します
|
1 |
$ verdaccio |

デフォルトポートは4873で立ち上がるのでhttp://localhost:4873/にアクセスします。
下記の画面が表示されていたら成功です。

2 パッケージの作成
レジストリサーバーはこれで一旦完了です。
次はパッケージを作成します。
ライブラリをパッケージ化するには、ライブラリのルートディレクトリにpackage.jsonファイルを置くだけです。
npmでおなじみのやつですが、中身が少し違います。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
{ "name": "jp.co.10antz.package4", "displayName": "10antz Package Number 4", "version": "1.0.0", "unity": "2018.1", "description": "This package provides X, Y, and Z. \n\nTo find out more, click the \"View Documentation\" link.", "keywords": ["key X", "key Y", "key Z"], "category": "Controllers", "dependencies": { "jp.co.10antz.package1": "1.0.0", "jp.co.10antz.package2": "2.0.0", "jp.co.10antz.package3": "3.0.0" } } |
| 名前 | 説明 | 記述例 |
|---|---|---|
| name※ | パッケージの名前、逆ドメインを使うのが一般的
後述するスコープと関係しているので命名規則に従う必要あり |
jp.co.10antz.[package name] |
| displayName※ | パッケージマネージャーに表示される名前 | |
| version※ | パッケージのバージョン | MAJOR.MINOR.PATCH |
| unity※ | 対象のUnityバージョン | |
| description※ | パッケージの説明 | |
| keywords | パッケージマネージャーで検索に利用される | |
| category | 用途不明 | |
| dependencies | パッケージが依存しているパッケージ | [package name] : [version] |
※は必須
アセンブリ定義
パッケージ化自体はとても簡単にできるのですが、ここでいくつか注意しなければ行けないことがあります。
パッケージ化したライブラリはAssets外(Library/PackageCache)にインストールされるため、
そのままではプロジェクト内のスクリプトから参照することが出来ません。
対応するにはAssembly Definition Filesと呼ばれるアセンブリ定義ファイルを設定する必要があります。
これはUnity2017.3から追加された機能で、Unityは基本的にすべてのスクリプトをAssembly-CSharp.dllにコンパイルしますが
アセンブリ定義を利用すると複数のアセンブリに分割することが出来ます。
そしてアセンブリ定義したパッケージはAssembly-CSharp.dllから自動的に参照されるため、
プロジェクト内のスクリプトからパッケージのスクリプトを参照することが可能になります。
Create -> Assembly Definition

またアセンブリ定義には他のアセンブリ定義への参照を設定することも出来るので、
依存関係のあるパッケージはここで参照の設定もする必要があります。
例えばCoreパッケージとModuleパッケージがあり、ModuleがCoreへ依存関係にある場合、
下記のようにCoreアセンブリ定義へ参照を設定します。

特殊なディレクトリ
パッケージにEditorディレクトリを含んでいる場合、別の注意事項があります。
通常UnityはEditorディレクトリ以下のスクリプトをAssembly-CSharp-Editor.dllにコンパイルするのですが、
Editorディレクトリをアセンブリ定義の対象にしてしまうと、Assembly-CSharp-Editor.dllの対象から外れてしまうため、
パッケージ内でUnityEditorの機能が使えなくなってしまいます。
この問題を回避するには、アセンブリ定義のプラットフォーム設定でEditorを選択します。

一つのパッケージでエディターとそれ以外のスクリプトを含む場合は下記のようなディレクトリ構成に分けて
アセンブリ定義をそれぞれ設定することをおすすめします。
|
1 2 3 4 5 6 7 |
├── Runtime/ │ ├── Runtime.cs │ └── Runtime.asmdef ├── Editor/ │ ├── Editor.cs │ └── Editor.asmdef └── package.json |
3 レジストリにパッケージを登録する
ここまででレジストリサーバーの立ち上げとパッケージの作成は完了したので、次はレジストリにパッケージを登録します
ユーザー登録とログイン
その前にレジストリにユーザーの登録とログインを済ませます
|
1 |
$ npm adduser --registry http://localhost:4873 |
ユーザー名・パスワード・Emailを聞かれるので入力します
以降はログインコマンドでログインします
|
1 |
$ npm login --registry http://localhost:4873 |
パッケージ登録
package.jsonを配置したディレクトリで下記コマンドを実行します
|
1 |
$ npm publish --registry http://localhost:4873 |
登録はこれで完了です

ちなみに同じパッケージは同じバージョンで登録することは出来ません
4 プロジェクトにパッケージをインストールする
レジストリの設定
UnityPackageManagerから自作パッケージをインストールするには
Packages/manifest.jsonを開いて下記のようにscopedRegistriesを追加するだけです。
|
1 2 3 4 5 6 7 8 9 |
"scopedRegistries": [ { "name": "10antz-package", "url": "http://localhost:4873/", "scopes": [ "jp.co.10antz.package" ] } ] |
urlにはレジストリサーバーのURLを入力します。
scopesはパッケージ名がスコープに含まれている場合、そのパッケージは指定したレジストリからインストールすることが出来ます。
またUnityPackageManagerにパッケージを一覧表示することも出来ます。
例えばパッケージ名がjp.co.10antz.package.coreの場合Managerに表示されますが、jp.co.10antz.core.packageの場合は表示されません。

これでUnityPackageManagerからインストール出来るようになりました。
補足
パッケージの依存関係
アセンブリ定義で依存関係にあるパッケージはアセンブリ定義に参照を設定する必要があると書きました。
パッケージの依存関係を設定するにはpackage.jsonのdependenciesにpackage name:versionのように記述します。
|
1 2 3 4 5 6 7 8 9 10 11 |
{ "name": "jp.co.10antz.package.module", "displayName": "10antz Package Module", "author": "y-harada", "version": "1.0.0", "unity": "2019.1", "description": "Package Test", "dependencies": { "jp.co.10antz.package.core": "1.0.0" } } |
これにより依存関係にあるパッケージは自動でインストールされます。
パッケージの削除
パッケージを削除するにはパッケージ名を指定してunpublishを実行します
|
1 |
$ npm unpublish [package name] --registry http://localhost:4873 |
@でバージョンを指定することで特定のバージョンを削除することも可能です
|
1 |
$ npm unpublish [package name]@[version] --registry http://localhost:4873 |
ポート設定
verdaccioのデフォルトポートは4873ですが、変更したい場合はconfig.yamlに下記を追加します。
localhost を変更することで特定のアドレスで立てることも可能です。
|
1 2 |
listen: - localhost:4873 |

デーモン化
このままではターミナルを閉じるとレジストリも終了してしまうのでpm2を使ってデーモン化します。
pm2をインストール
|
1 |
$ npm install -g pm2 |
verdaccio起動
|
1 |
$ pm2 start verdaccio |
statusコマンドでverdaccioが表示されていたら成功です。

参考サイト
Unity Package Manager
https://docs.unity3d.com/Packages/com.unity.package-manager-ui@2.1/manual/index.html
Scoped package registries
https://docs.unity3d.com/Manual/upm-scoped.html
Assembly Definitions
https://docs.unity3d.com/Manual/ScriptCompilationAssemblyDefinitionFiles.html