はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】PackageManager.Clientを利用してC#スクリプトを通してPackageManagerを操作する

はじめに

今回はPackageManagerのスクリプティングAPIについて取り上げたいと思います。

docs.unity3d.com

概要

PackageManagerを操作するためにはPackageManager.Clientクラスを利用します。

  • LogLevel : 使用するログレベル
  • Add : パッケージ追加
  • AddAndRemove : 一括でパッケージ追加・削除
  • Embed : プロジェクトにパッケージを埋め込む
  • List : パッケージの一覧取得
  • Pack : パッケージをGZipで圧縮して出力
  • Remove : パッケージ削除
  • Resolve : 変更されたパッケージや不足しているパッケージの再インストール、不要なパッケージの削除を行う
  • Search : 指定したパッケージ検索
  • SearchAll : 互換性のある検出可能なパッケージを全て検索

docs.unity3d.com

使い方

代表的なものを抜き出して具体的な利用方法を紹介します。

LogLevel

[MenuItem("Tools/PackageManager/LogLevel")]
public static void GetLogLevel()
{
    // PackageManagerがEditor.logとupm.logにログを記録するときに使用するログレベルの取得・設定。デフォルトはLogLevel.Info
    // NOTE: Error < Warn < Info < Verbose < Debug < Silly
    LogLevel logLevel = Client.LogLevel;
    Debug.Log(logLevel);
}
// 出力例
Info

Add

[MenuItem("Tools/PackageManager/Add")]
public static void Add()
{
    // パッケージの追加
    // NOTE: Client.Addは非同期操作なので、AddRequestインスタンスを使用して監視・結果の取得を行う必要がある
    AddRequest addRequest = Client.Add("com.unity.textmeshpro");
    EditorApplication.update += Progress;
        
    void Progress()
    {
        if (addRequest.IsCompleted)
        {
            if (addRequest.Status == StatusCode.Success)
            {
                Debug.Log("Installed: " + addRequest.Result.packageId);
            }
            else if(addRequest.Status >= StatusCode.Failure)
            {
                Debug.Log(addRequest.Error.message);
            }
            EditorApplication.update -= Progress;
        }
    }
}
// 出力例
Installed: com.unity.textmeshpro@3.0.6

AddAndRemove

一つ一つAddRemoveするよりも効率が良いです。

[MenuItem("Tools/PackageManager/AddAndRemove")]
public static void AddAndRemove()
{
    // パッケージの一括追加・削除
    // NOTE: nullや空の値が含まれる場合はArgumentExceptionが投げられる
    // NOTE: Client.AddAndRemoveは非同期操作なので、AddRequestインスタンスを使用して監視・結果の取得を行う必要がある
    string[] packagesToAdd = new[] { "https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask" };
    string[] packagesToRemove = new[] { "com.unity.textmeshpro" };
    AddAndRemoveRequest andRemoveRequest = Client.AddAndRemove(packagesToAdd, packagesToRemove);
    EditorApplication.update += Progress;
        
    void Progress()
    {
        if (andRemoveRequest.IsCompleted)
        {
            if (andRemoveRequest.Status == StatusCode.Success)
            {
                foreach (PackageInfo packageInfo in andRemoveRequest.Result)
                {
                    Debug.Log(packageInfo.packageId);
                }
            }
            else if(andRemoveRequest.Status >= StatusCode.Failure)
            {
                Debug.Log(andRemoveRequest.Error.message);
            }
            EditorApplication.update -= Progress;
        }
    }
}
// 出力例
com.cysharp.unitask@https://github.com/Cysharp/UniTask.git?path=src/UniTask/Assets/Plugins/UniTask
以下省略

List

[MenuItem("Tools/PackageManager/List")]
public static void List()
{
    // プロジェクトが依存しているパッケージをリストアップ
    // offlineMode: remote Unity package registryからパッケージの最新情報を要求するかどうか
    // includeIndirectDependencies: 間接的に依存しているパッケージを含めるかどうか
    ListRequest listRequest = Client.List(offlineMode: false, includeIndirectDependencies: false);
    EditorApplication.update += Progress;

    void Progress()
    {
        if (listRequest.IsCompleted)
        {
            if (listRequest.Status == StatusCode.Success)
            {
                foreach (PackageInfo packageInfo in listRequest.Result)
                {
                    Debug.Log("PackageName : " + packageInfo.name);
                }
            }
            else if (listRequest.Status >= StatusCode.Failure)
            {
                Debug.Log(listRequest.Error.message);
            }
            EditorApplication.update -= Progress;
        }
    }
}
// 出力例
PackageName : com.cysharp.unitask
PackageName : com.unity.collab-proxy
以下省略

Embed

補足ですがPackagesにファイルが必ずなければ動作しないわけではありません。

[MenuItem("Tools/PackageManager/Embed")]
public static void Embed()
{
    // プロジェクトにパッケージを埋め込みます(Packagesフォルダーに格納する)
    var embedRequest = Client.Embed("com.unity.textmeshpro");
    EditorApplication.update += Progress;

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

            EditorApplication.update -= Progress;
        }
    }
}
// 出力例
Embedded: com.unity.textmeshpro@file:/Users/-------/Test2022_3_0f1/Packages/com.unity.textmeshpro

埋め込みの依存関係 - Unity マニュアル

Remove

[MenuItem("Tools/PackageManager/Remove")]
public static void Remove()
{
    // パッケージの削除
    var removeRequest = Client.Remove("com.unity.textmeshpro");
    EditorApplication.update += Progress;

    void Progress()
    {
        if (removeRequest.IsCompleted)
        {
            if (removeRequest.Status == StatusCode.Success)
            {
                Debug.Log("remove");
            }
            else if (removeRequest.Status >= StatusCode.Failure)
            {
                Debug.Log(removeRequest.Error.message);
            }

            EditorApplication.update -= Progress;
        }
    }
}
// 出力例
remove

Resolve

[MenuItem("Tools/PackageManager/Resolve")]
public static void Resolve()
{
    // プロジェクトのパッケージを解決する
    // 変更されたパッケージ・不足しているパッケージの再インストールや不要なパッケージの削除
    Client.Resolve();
}