1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

Organization

PackageManagerから必要なPackageをインポートする

はじめに

はやく民主化して
こんにちは、アドベントカレンダー19日目担当の避雷です。unitypackageを配布したことのある人の中には、相手方と自分のプロジェクトに入っているリソースの乖離に苦しんだことがある人もいると思います。
例えばこっちがPPSv2でイイ感じの画を提供していても、インポート先のProjectにPackageManagerのPostProcessingが入っていなければその魅力を伝えることが出来ません。
今回はEditor拡張を用いてPackageManagerを操作する方法を調べてみましょう。

PackageManagerを操作する

PackageManagerに対する基本的な操作はUnityEditor.PackageManagerで行います。
https://docs.unity3d.com/ja/2017.4/ScriptReference/PackageManager.Client.html

インポートされているパッケージの一覧を取得

インポートされているパッケージの一覧を取得するには、Client.Listを使います。Listの返り値はListRequestです。
https://docs.unity3d.com/ja/2017.4/ScriptReference/PackageManager.Client.List.html
返り値の名称からもわかるように、この関数は非同期で実行されます。ListRequestはStatus,Resultなどの変数を持つので、これらを参照して非同期的に書きましょう。
↓サンプルコード(インポートされたすべてのpackageを出力)

using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEditor;
using UnityEditor.PackageManager;
using UnityEngine;

public class ListPackage
{
    [MenuItem("PackageManager/List")]
    static async void List()
    {
        var listRequest = Client.List();
        while (listRequest.Status == StatusCode.InProgress)
        {
            await Task.Delay(100);
        }

        if (listRequest.Status == StatusCode.Success)
        {
            var result = "";
            foreach (var package in listRequest.Result)
            {
                result += package.packageId + "\n";
            }
            Debug.Log(result);
        }

        if (listRequest.Status == StatusCode.Failure)
        {
            Debug.Log("Error!");
        }

    }

}

MenuItemアトリビュートによってUnityEditorのメニューバーにPackageManagerの欄が追加されていると思うので、Listをクリックしてみましょう。一瞬のディレイの後、以下のようなログが出力されます。
image.png

image.png

Hoge@hugaと言うのがそれぞれのpackageのpackageIDです。
@より前がpackageの名前、@より後がpackageのversionです。
現在はcom.unity.hogeとなっている(つまりUnity公式の)packageしかありませんが、将来的にPackageManagerが使えるようになれば、他の人がPackageをインポートすることが出来るようになるはずです。

パッケージを指定してインポートする

新しくpackageをインポートするときはClient.Addを使います。Addの返り値はAddRequestです。
これを実行するとプログレスバーが表示され、通常の方法でのpackageのinstallと同じようにインポートされます。
https://docs.unity3d.com/ja/2017.4/ScriptReference/PackageManager.Client.Add.html
Listと同様非同期で処理されます。引数のpackageIdOrNameは、nam(@の前)だけを指定すると最新版をインポートしてくれるようになっています。packageIDによってバージョン(@の後ろ)まで指定すれば、古いバージョンのpackageをインポートしてくれます。
↓サンプルコード(適当なpackageをインポートする)


同様にメニューバーにAddがあるはずなので押してみます。今回はPostProcessingを直打ちして最新版をインストールするようにしています。しばらく経過すると下記のようなプログレスバーが出てきて、インポートの進捗を伝えてくれます。
image.png

更に暫くすれば、AddRequest.StatusがSuccessとなり、以下のようなログが出力されます。
image.png

Packageを見るとちゃんとPostProcessingがインストールされていることが分かります。
image.png

既にインストールされているpackageについては何も起こりません。(特に処理が行われず、Succeededとなる)

unity packageをインポートした直後にPackageManagerを呼びたい

[InitializeOnLoad]アトリビュートを付けることによって、UnityEditor起動時とそのクラス自身のコンパイル時にクラスのコンストラクタが走るようになります。
ここに先ほどの処理を書けばunitypackageインポート直後にpackageをインストールすることが出来ます(UnityPackageとPackageManagerのpackageで紛らわしいですね…)
ただし、コンストラクタ自身はasyncを付けることが出来ないため、コンストラクタ内で別の非同期メソッドを走らせるようにしましょう。

おわりに

他のIDEにおけるNugetのような役割を果たしているPackageManagerですが、現在はpublicなrepositoryをjson直書きで登録できるみたいですが、そのうち民主化されて楽にPackageが公開されるようになるといいですね。
個人的にはPackageで追加されるアセット類はgitで共有せずに済むところが気に入っています。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
1
Help us understand the problem. What are the problem?