こんにちは、株式会社Synamonのエンジニアの岡村(@Sokuhatiku)です。
前回、任意のフォルダにPackage.jsonを定義することで、ローカルパス参照でUnityPackageManagerに載せることが出来る方法を書きました。
ただし、その方法はローカルのファイルパスを直接指定してパッケージとして扱うというもので、バージョン管理やチーム内での共有のしやすさに難がありました。
今回、その部分の解決策を見つけました。それと近いタイミングで、@kohki_nakajiさんに前回の記事を紹介して頂けて、さらに、今回の記事にも興味があると言って頂けたため、手順を纏めてみました。
おことわり
※今回はUnityとnpmの狭間に自作パッケージを無理やりねじ込む所に焦点を当てている為、LAN内に公開する方法には触れていません。ご了承ください。
※今回紹介する方法はハックです。公式サポートされている機能ではないので、今後情報が古くなったり、利用できなくなる可能性が大いにあります。
自作パッケージレジストリ
前回、UnityPackageManager(以下、upm)はnpmの仕組みを利用しているという所まで調査できていました。
upmとnpmのもつjsonを比べてみると非常によく似ていた為、npmのレジストリを立て、Nodeの代わりにUnityPackageを置けば、そこからダウンロード出来るのではないかという予想を立てました。
そこで、Verdaccioというツールを利用して、ローカル環境にnpmレジストリを立ててみたところ、いくつかハマりどころがあったものの、上手くいきました。 github.com
Verdaccioは、npmのレジストリを好きな場所に立てる事ができるツールです。また、uplinkとして他のレジストリを設定した場合、自身が持っていないパッケージをそちらからダウンロードすることが出来るようになります。
ハマりどころ
先にハマりどころを紹介しておきます。
upmはポート付きアドレスを認識しない
Verdaccioを立てると4873番ポートで起動するのですが、そのままlocalhost:4873をUnityにレジストリとして設定しても、パッケージの読み込みに失敗します。 簡単な解決方法は、verdaccio側に80番ポートで待受させることです。
upmはスコープを認識しない
npmには@{ユーザー名}/{名前}というパッケージ名にする事でパッケージ名の重複を防ぐ、スコープという機能がありますが、これをupmは認識しません。不正なパッケージ名として弾かれてしまいます。
VerdaccioのuplinkにUnityのレジストリを登録しないとプロジェクトオープンに失敗する
Unityはプロジェクトを開く際に、パッケージの問い合わせを行います。その際、Unity側のパッケージが取得できなければ、ロード失敗になります。
VerdaccioにUnityのレジストリを登録しているとパッケージのアップロードに失敗する
Verdaccioは、パッケージのアップロード時に既存のパッケージを確認するのですが、Unityのレジストリが返してくるjsonを解釈できないらしく、エラーが出てアップロードが止まってしまいます。 今回はその解決策として、unity公式のパッケージ名に必ず付いている、「com.unity」ドメインにのみuplinkを設定することで対処しています。(なので、com.unityでパッケージをアップロードしようとすると失敗します。)
Unity上のGUIに自作パッケージは出てこない
UnityのPackage Manager GUIのAllタブに表示されるパッケージ一覧はどうやら別の手段で取得しているらしく、自作パッケージをアップロードしてもリストに表示されません。インストールにはmanifest.jsonを弄る必要があります。
…さあ、これらを踏まえてレジストリを立てましょう。
レジストリを立てる
今回はnpmの事を知らない人向けに(僕もよく知らなかったので…)インストール方法から書いていこうと思います。環境はWindows10です。
Verdaccioはnpmからインストールしますので、まずnpmを入手する必要があります。npmはNode.jsのパッケージマネージャーであり、Node.jsをインストールすると付いてきます。
Node.jsのインストールが終わったらnpmコマンドが使えるようになるので、コマンドプロンプトを開いてverdaccioをインストールします。
npm install -g verdaccio
npmの提供するアプリ(Node)はデフォルトだとコマンドを叩いたディレクトリにインストールされますが、今回は-g引数を使い、PCのどこからでも触れるようグローバルインストールを行います。
インストールが終わったら起動します。
verdaccio
何も設定をいじっていない状態なので、localhost:4873でアクセス出来るはずです。
設定の変更
Verdaccioを一度立ち上げたことで設定ファイルが作成されます。UnityPackageを配布するために、設定を変更しましょう。一度Verdaccioを落とします。
設定ファイルは、%APPDATA%\verdaccio\config.yamlに生成されているはずです。
ファイルを開き、次のように書き換えます。
| # | |
| # This is the default config file. It allows all users to do anything, | |
| # so don't use it on production systems. | |
| # | |
| # Look here for more config file examples: | |
| # https://github.com/verdaccio/verdaccio/tree/master/conf | |
| # | |
| # path to a directory with all packages | |
| storage: ./storage | |
| # path to a directory with plugins to include | |
| plugins: ./plugins | |
| listen: localhost:80 | |
| web: | |
| # WebUI is enabled as default, if you want disable it, just uncomment this line | |
| #enable: false | |
| title: Verdaccio | |
| auth: | |
| htpasswd: | |
| file: ./htpasswd | |
| # Maximum amount of users allowed to register, defaults to "+inf". | |
| # You can set this to -1 to disable registration. | |
| #max_users: 1000 | |
| # a list of other known repositories we can talk to | |
| uplinks: | |
| unity: | |
| url: https://packages.unity.com | |
| packages: | |
| 'com.unity.*': | |
| access: $all | |
| publish: $authenticated | |
| proxy: unity | |
| '**': | |
| # allow all users (including non-authenticated users) to read and | |
| # publish all packages | |
| # | |
| # you can specify usernames/groupnames (depending on your auth plugin) | |
| # and three keywords: "$all", "$anonymous", "$authenticated" | |
| access: $all | |
| # allow all known users to publish packages | |
| # (anyone can register by default, remember?) | |
| publish: $authenticated | |
| # To use `npm audit` uncomment the following section | |
| middlewares: | |
| audit: | |
| enabled: true | |
| # log settings | |
| logs: | |
| - {type: stdout, format: pretty, level: http} | |
| #- {type: file, path: verdaccio.log, level: info} | |
(リビジョンでどのように書き換えたか分かります。)
完了したら、もう一度Verdaccioを起動しましょう。設定ファイルでポートを変更したので、今度はポート無しのlocalhostでアクセスできるようになります。
ユーザーの作成
次にアップロードするためのユーザーを作成します。
npm adduser --registry http://localhost/
User名、Password、Emailアドレスを順番に聞かれるので設定してください。このユーザー情報はVerdaccioのwebページにサインインするのに使うと共に、Verdaccioにパッケージをアップロードする際にも自動的に使用されます。
パッケージのアップロード
パッケージの作り方に関しては、前回の記事を参照してください。
Unity Package Managerに自作Packageを登録する方法 - Synamon’s Engineer blog
パッケージを作ったら、package.jsonのあるディレクトリに移動して、以下のコマンドを叩きます。
npm publish --registry "http://localhost/"
これでパッケージのアップロードは完了です。
インポート先のプロジェクトの設定
後は、作ったパッケージをインポートしたいプロジェクトの、Packages\manifest.jsonを設定します。
dependenciesに、"{パッケージ名}": "{パッケージのバージョン}"を追加して、dependenciesキーの後ろに"registry": "http://localhost/"を追加してください。
このようになるはずです(dependenciesの中身はプロジェクトによって異なります。)
{ "dependencies": { "com.test.testpackage": "0.8.2", "com.unity.package-manager-ui": "1.9.11", "com.unity.postprocessing": "2.0.10-preview", "com.unity.progrids": "3.0.3-preview.0" }, "registry": "http://localhost/" }
("com.test.testpackage": "0.8.2"の部分を自作パッケージの名前とバージョンに変換してください。あと、"registry"の前のコンマを忘れずに!)
以上です。お疲れ様でした。これでUnityを起動すると、パッケージが読み込まれているはずです。
バージョンを変えて複数回アップロードすると、UI上からバージョン切替も出来ます。
ちなみにアップロードしたパッケージの削除は以下のコマンドです。
npm unpublish {パッケージ名} --force --registry "http://localhost/"
あとがき
今回、自作パッケージのバージョン管理や、バージョン名でインストール(=ローカルにファイルをコピーしてくる必要が無い)まで解決することが出来ましたが、まだ問題点があります。
個人的に大きいのはパッケージ間の依存関係を解決できない事です。パッケージ内のdependencyに他のパッケージを指定してもロードして貰えません。 流石にここはupmの内部挙動のため、外からハックして解決するのは難しいのでは、と感じています。
とはいえ、今回で、チーム内で前提アセットを配布+git管理するといった使い方はかなりやりやすくなったと思います。Unityの公式対応が待てない方は是非試してみてください。
また、上手くいかなかったり、もっといい方法があれば是非教えてください。