Version: 2021.2
言語: 日本語
Package Manifest ウィンドウ
パッケージアセットへのアクセス

パッケージ用のスクリプティング API

Package Manager のスクリプティング API を使用して、C# スクリプトを通して Package Manager を操作できます。例えば、ターゲットマシンのプラットフォームに応じて、特定のパッケージやバージョンをインストールしたい場合などです。

システムは、PackageManager.Client クラスに著しく依存しています。これを使うと、パッケージの検索、パッケージのリストの参照、スクリプトによるパッケージのインストールとアンインストールをスクリプト経由で行えます。

もう 1 つの重要なクラスは PackageManager.PackageInfo です。これには、パッケージマニフェストとレジストリから取得したメタデータを含む、パッケージの状態が含まれます。例えば、パッケージで使用可能なバージョンのリストや、パッケージの検索やインストール中に発生する可能性があるエラーリストを取得できます。

プロジェクトにパッケージを追加

この例では、Client クラスを使用してプロジェクトにパッケージをインストールまたは加える方法を示しています。

パッケージを加えるには Client.Add を使用します。Client.Add メソッドを呼び出すと、パッケージ名だけを指定することも、特定のバージョンをもつ名前を指定することもできます。例えば、Client.Add("com.unity.textmeshpro") を使用すると、TextMesh Pro パッケージの最新バージョンがインストールされます (または最新バージョンに更新されます)。Client.Add("com.unity.textmeshpro@1.3.0") を使用すると、TextMesh Pro パッケージのバージョン 1.3.0 がインストールされます。

Client.Add メソッドは AddRequest インスタンスを返します。これを利用して、状態やエラーを把握できます。また、新しく加えられたパッケージの PackageInfo 情報を含む Request レスポンスを取得できます。

using System;
using UnityEditor;
using UnityEditor.PackageManager.Requests;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example {
   static class AddPackageExample
   {
       static AddRequest Request;

       [MenuItem("Window/Add Package Example")]
       static void Add()
       {
           // Add a package to the project
           Request = Client.Add("com.unity.textmeshpro");
           EditorApplication.update += Progress;
       }

       static void Progress()
       {
           if (Request.IsCompleted)
           {
               if (Request.Status == StatusCode.Success)
                   Debug.Log("Installed: " + Request.Result.packageId);
               else if (Request.Status >= StatusCode.Failure)
                   Debug.Log(Request.Error.message);

               EditorApplication.update -= Progress;
           }
       }
   }
}

プロジェクト内のパッケージのリストを参照

この例は、Client クラスを使用してプロジェクト内のパッケージを繰り返し使用する方法を示しています。

Client.List メソッドは ListRequest インスタンスを返します。これを利用して、List オペレーションやエラーの状態を把握できます。また、繰り返し使うパッケージの PackageInfo 情報を含む Request レスポンスを取得できます。

using System;
using UnityEditor;
using UnityEditor.PackageManager.Requests;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example {
   static class ListPackageExample
   {
       static ListRequest Request;

       [MenuItem("Window/List Package Example")]
       static void List()
       {
           Request = Client.List();    // List packages installed for the project
           EditorApplication.update += Progress;
       }

       static void Progress()
       {
           if (Request.IsCompleted)
           {
               if (Request.Status == StatusCode.Success)
                   foreach (var package in Request.Result)
                       Debug.Log("Package name: " + package.name);
               else if (Request.Status >= StatusCode.Failure)
                   Debug.Log(Request.Error.message);

               EditorApplication.update -= Progress;
           }
       }
   }
}

プロジェクトにパッケージを埋め込む

この例は、Client クラスを使用して、すでにプロジェクトにインストールされているパッケージの 1 つを埋め込む方法を示しています。メインメソッドである Client.Embed は、パッケージのコピーを作成し、プロジェクトの Packages フォルダーに格納します。

Client.Embed メソッドはEmbedRequest インスタンスを返します。これを利用して、Embed オペレーションやエラーの状態を把握できます。また、新しく埋め込まれたパッケージの PackageInfo 情報を含む Request レスポンスを取得できます。

以下の例でも Client.List メソッドを使用し、現在プロジェクトにインストールされているパッケージの集合にアクセスし、埋め込みでもビルトインでもない最初のパッケージを選択します。

Client.List メソッドは ListRequest インスタンスを返します。これを利用して、List オペレーションやエラーの状態を把握できます。また、繰り返し使うパッケージの PackageInfo 情報を含む Request レスポンスを取得できます。

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.PackageManager.Requests;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example
{
    static class EmbedPackageExample
    {
        static String targetPackage;
        static EmbedRequest Request;
        static ListRequest LRequest;

        [MenuItem("Window/Embed Package Example")]
        static void GetPackageName()
        {
            // まず、インストールされたパッケージの名前を取得します
            LRequest = Client.List();
            EditorApplication.update += LProgress;
        }

        static void LProgress()
        {
            if (LRequest.IsCompleted)
            {
                if (LRequest.Status == StatusCode.Success)
                {
                    foreach (var package in LRequest.Result)
                    {
                        // 現在、プロジェクトにインストールされていて、ビルトインでもなく
                        // すでに埋め込まれているものでもないパッケージのみを取得します
                        if (package.isDirectDependency && package.source
                            != PackageSource.BuiltIn && package.source
                            != PackageSource.Embedded)
                        {
                            targetPackage = package.name;
                            break;
                        }
                    }

                }
                else
                    Debug.Log(LRequest.Error.message);

                EditorApplication.update -= LProgress;

                Embed(targetPackage);

            }
        }

        static void Embed(string inTarget)
        {
            // プロジェクトにパッケージを埋め込みます
            Debug.Log("Embed('" + inTarget + "') called");
            Request = Client.Embed(inTarget);
            EditorApplication.update += Progress;

        }

        static void Progress()
        {
            if (Request.IsCompleted)
            {
                if (Request.Status == StatusCode.Success)
                    Debug.Log("Embedded: " + Request.Result.packageId);
                else if (Request.Status >= StatusCode.Failure)
                    Debug.Log(Request.Error.message);

                EditorApplication.update -= Progress;
            }
        }
    }
}

Package Manager イベント

Events クラスを使用して、イベントハンドラーを Package Manager に登録します。Events クラスには、サブスクライブ可能な 2 つのイベントが含まれています。それらは、Package Manager が以下のタイミングで発生させます。

  • Package Manager が依存関係のリストを変更する直前 (registeringPackages)
  • Package Manager がパッケージの依存関係の変更されたリストをインポートしてコンパイルした後 (registeredPackages)

以下の例では、これらのイベントの使用方法を示しています。

RegisterPackages イベントの使用例

using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example
{
    public class EventSubscribingExample_RegisteringPackages
    {
        public EventSubscribingExample_RegisteringPackages()
        {
            // 追加オペレーター (+=) を使ってイベントをサブスクライブ 
            // イベントが発生すると、ハンドラー内のコードを実行します
            Events.registeringPackages += RegisteringPackagesEventHandler;
        }

        // メソッドは PackageRegistrationEventArgs イベント引数を取得します
        void RegisteringPackagesEventHandler(PackageRegistrationEventArgs packageRegistrationEventArgs)
        {
            Debug.Log("The list of registered packages is about to change!");

           foreach (var addedPackage in packageRegistrationEventArgs.added)
            {
                Debug.Log($"Adding {addedPackage.displayName}");
            }

            foreach (var removedPackage in packageRegistrationEventArgs.removed)
            {
                Debug.Log($"Removing {removedPackage.displayName}");
            }

            //  changedFrom と changedTo コレクションには、更新されようとしているパッケージが含まれています。
            // 両方のコレクションは、パッケージ名が一致するインデックスを持ち同じサイズであることが保証されています。
            for (int i = 0; i <= packageRegistrationEventArgs.changedFrom.Count; i++)
            {
                var oldPackage = packageRegistrationEventArgs.changedFrom[i];
                var newPackage = packageRegistrationEventArgs.changedTo[i];

                Debug.Log($"Changing ${oldPackage.displayName} version from ${oldPackage.version} to ${newPackage.version}");
            }
        }
    }
}

registeredPackages イベントの使用例

using UnityEditor;
using UnityEditor.PackageManager;
using UnityEngine;

namespace Unity.Editor.Example
{
    public class EventSubscribingExample_RegisteredPackages
    {
        // イベントをサブスクライブするには '[InitializeOnLoadMethod]' か '[InitializeOnLoad]' を使う必要があります
        [InitializeOnLoadMethod]
        static void SubscribeToEvent()
        {
            // これにより、エディターがパッケージの新しいリストを登録した後にメソッドが呼び出されます。
            Events.registeredPackages += RegisteredPackagesEventHandler;
        }

        static void RegisteredPackagesEventHandler(PackageRegistrationEventArgs packageRegistrationEventArgs)
        {
            // ここで実行されるコードは、エディターが一連の新しいパッケージのコンパイルを完了したと安全に想定できます。
            Debug.Log("The list of registered packages has changed!");
        }
    }
}
Package Manifest ウィンドウ
パッケージアセットへのアクセス