mcpField
U
unity-package-management

unity-package-management

github.com/unity-technologies開発1.2k7.5k 回インストール1 日前に更新
リポジトリ

unity-package-management について

unity-package-management は、Unity プロジェクトの保守担当者向けのスキルガイドです。Pipeline コマンドによる UPM パッケージ管理と、Editor コマンドが使えない場合の C# Client API による代替手順を説明し、検索、バージョン確認、ヘッドレスインストールも扱います。

主な機能

  1. 01UPMパッケージの追加・削除・更新
  2. 02パッケージ検索と利用可能なバージョン確認
  3. 03Pipelineコマンドを優先して利用
  4. 04Editorがない場合のC#スクリプト代替
  5. 05ヘッドレスでのインストールと検証
  6. 06アセットのインポートと.metaファイル生成

活用シーン

  1. 01既存のUnityプロジェクトに依存関係を設定
  2. 02CIでパッケージを非対話インストール
  3. 03導入前にパッケージIDとバージョンを確認
  4. 04ヘッドレスでアセットをインポートしメタデータを生成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/unity-technologies/skills --skill unity-package-management

インストール後、Claude Code で/unity-package-managementを入力して読み込まれたか確認します。

同梱ファイルreferences/select-packages.md

詳細

Unity パッケージ管理(まず Pipeline コマンドを使用し、C# スクリプトはフォールバックとして使用)

プロジェクトの Pipeline パッケージにある package コマンドを unity command 経由で実行し、UPM(Unity Package Manager)パッケージを追加、削除、アップグレード、検索します。これらのコマンドに応答できる Editor がない場合に限り、スクリプトからヘッドレスで実行する UnityEditor.PackageManager.Client にフォールバックします(フォールバックを参照)。**Packages/manifest.json を手動で編集しないでください。**Package Manager は依存関係と互換性のあるバージョンを正しく解決しますが、手動編集では解決が頻繁に壊れます。

このガイドは、Editor のインストール、プロジェクトの作成、ビルド/テストを扱う unity-cli スキルを補完するものです。同スキルでは unity command、unity status、unity pipeline install について説明しています。

まず package コマンドを使用する

Pipeline パッケージは add、remove、list、resolve、search、status の package コマンドグループを登録します。これらのコマンドを使うには、プロジェクトに com.unity.pipeline が含まれた状態で Editor が起動している必要があります(unity pipeline install で追加し、次に unity open を実行し、unity status --until-ready で準備ができるまで待ちます)。各コマンドのパラメーターは Editor から取得するため、最初の呼び出しの前に確認してください。パラメーター名を推測しないでください。

unity status --until-ready --project-path "<project-path>"
unity command package --project-path "<project-path>"                  # the package commands this Editor has
unity command --query package --format json --project-path "<project-path>"   # each command's parameter schema
unity command package search --project-path "<project-path>"           # then pass the parameters the schema lists
unity command package add --project-path "<project-path>"              # add one or more packages by id
unity command package list --project-path "<project-path>"             # confirm what is installed

コマンドのパラメーターは、スキーマに記載された名前を使ってコマンド名の後に渡します(unity command <group> <command> --<parameter> <value>)。スキーマが複数の ID を受け付ける場合は、必要なパッケージをすべて 1 回の package add 呼び出しで追加してください。最低バージョンが必要な場合は、スキーマの説明に従ってバージョンを指定します(@<version> 形式の ID は、後述の C# フォールバックで使用します)。package status または package list で確認し、パッケージを削除するには package remove を使用します。終了コードがゼロ以外の場合は失敗とみなし、メッセージを確認してください。

unity command package でそのようなグループがないと報告される場合、プロジェクトの Pipeline パッケージが古いバージョンです。unity pipeline upgrade を実行するか、以下のフォールバックを使用してください。

使用する場面

  • 既存または新規作成したプロジェクトで、1 つ以上のパッケージを追加/削除/アップグレードする場合。
  • CI でプロジェクトのパッケージを非対話的にセットアップする場合(Editor が起動していないときはフォールバックのスクリプトを使用)。
  • パッケージ ID が存在するか確認する場合、または依存する前に利用可能なバージョンを調べる場合。
  • ゲームに実際に必要なパッケージを決める場合。references/select-packages.md を参照してください。

インストールするものを選ぶ

すべてではなく、プロジェクトが実際に必要とするものをインストールしてください。選択したテンプレートにすでに含まれているパッケージを優先します(URP テンプレートには、レンダーパイプライン、Input System などがすでに含まれています)。ジャンル/外観/プラットフォーム/収益化に応じたパッケージの対応関係と、レジストリの検索方法については、references/select-packages.md を参照してください。重複のないパッケージ ID のリストを作成し、インストール前にユーザーに読み上げて確認してください。

フォールバック:問い合わせ可能な Editor がない場合(C# Client API)

package add を実行できない場合に限り、このセクションを使用してください。Editor が起動しておらず、起動する予定もない場合、プロジェクトに Pipeline パッケージがない場合、またはコマンドグループがなくアップグレードも希望しない場合が該当します。Editor がバッチモードで実行するスクリプトから Client.AddAndRemove を呼び出してインストールします。

-quitの問題 — インストールにunity runを使ってはいけない理由

Client.Add / Client.AddAndRemoveは非同期です。後続のEditorApplication.updateティックで完了するRequestを返します(UPMの子プロセスは、Editorのメインループポンプで結果をマーシャリングして返すため、ブロッキングするwhile (!req.IsCompleted)のビジーウェイトではデッドロックします)。リクエストが完了するまで、-executeMethodが戻った後もEditorを起動したままにする必要があります。

インストーラーにunity runは使えません。デフォルトの実行パスでは-quitが挿入されるためです(unity-cliスキルの予約済みフラグを参照)。-quitを指定すると、メソッドが戻った直後にEditorが終了します。UPMの解決が完了する前なので、パッケージはインストールされず、コールバックも実行されません。

解決方法: -quitを指定せず、-batchmodeでEditorのバイナリを直接起動します。Editorは起動したままになり、EditorApplication.updateのティックが続き、ポーリングコールバックが実行されます。処理が終わるとコールバックがEditorApplication.Exit(code)を呼び出し、Editorの終了とプロセスの終了コードの設定を行います。

インストーラースクリプト

これをAssets/Editor/ProjectBootstrap/PackageInstaller.csに記述します。UnityEditorを使用するため、Editor/フォルダー内(またはEditor専用アセンブリ内)に配置する必要があります。

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

namespace ProjectBootstrap
{
    // Installs (and optionally removes) a fixed set of packages via the PackageManager
    // Client API, headless-safe.
    public static class PackageInstaller
    {
        // EDIT this list to match the package selection (see references/select-packages.md).
        static readonly string[] PackagesToAdd =
        {
            "com.unity.inputsystem",
            "com.unity.cinemachine",
            "com.unity.render-pipelines.universal",
            // "[email protected]"  // pin a version with @ when a minimum is required
        };

        // Optionally drop packages in the same resolution pass (e.g. a template default you don't want).
        static readonly string[] PackagesToRemove = { };

        const double TimeoutSeconds = 600; // UPM resolution + downloads can be slow

        static AddAndRemoveRequest _request;
        static double _deadline;

        // Invoke with: -executeMethod ProjectBootstrap.PackageInstaller.Install  (NO -quit)
        public static void Install()
        {
            if (PackagesToAdd.Length == 0 && PackagesToRemove.Length == 0)
            {
                Debug.Log("[PackageInstaller] Nothing to do.");
                EditorApplication.Exit(0);
                return;
            }

            Debug.Log($"[PackageInstaller] Adding: {string.Join(", ", PackagesToAdd)}");
            _request = Client.AddAndRemove(packagesToAdd: PackagesToAdd, packagesToRemove: PackagesToRemove);
            _deadline = EditorApplication.timeSinceStartup + TimeoutSeconds;
            EditorApplication.update += Poll;
        }

        static void Poll()
        {
            if (_request == null) return;

            if (!_request.IsCompleted)
            {
                if (EditorApplication.timeSinceStartup > _deadline)
                {
                    EditorApplication.update -= Poll;
                    Debug.LogError("[PackageInstaller] Timed out waiting for UPM.");
                    EditorApplication.Exit(2);
                }
                return;
            }

            EditorApplication.update -= Poll;

            if (_request.Status == StatusCode.Success)
            {
                var names = _request.Result.Select(p => $"{p.name}@{p.version}");
                Debug.Log($"[PackageInstaller] Resolved: {string.Join(", ", names)}");
                EditorApplication.Exit(0);
            }
            else
            {
                Debug.LogError($"[PackageInstaller] Failed: {_request.Error?.message}");
                EditorApplication.Exit(1);
            }
        }
    }
}

AddAndRemoveは、UPMの解決処理1回でパッケージ一式をインストールします。パッケージごとにClient.Addを呼び出すより速く、エラーも発生しにくくなります。

1つのスクリプトで追加/削除/アップグレードする方法:

  • 追加:IDをPackagesToAddに記載します。
  • 削除:IDをPackagesToRemoveに記載します。
  • アップグレード/バージョン固定:@<version>を付けてIDを追加します(例:[email protected])。バージョンを指定しない場合、解決時に互換性のある最新リリースが選択されます。

パッケージの検索/検証

IDが存在することを確認したり、追加前にバージョン一覧を取得したりするには、レジストリを検索します。Editor内のClient.SearchAll() / Client.Search("<id>")の呼び出しも非同期のため、インストーラーと同じポーリングとExitのパターン、および同じヘッドレス実行方法を使用します。Assets/Editor/ProjectBootstrap/PackageSearch.csを作成します。

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

namespace ProjectBootstrap
{
    public static class PackageSearch
    {
        const double TimeoutSeconds = 120;
        static SearchRequest _request;
        static double _deadline;

        // Invoke with: -executeMethod ProjectBootstrap.PackageSearch.SearchAll  (NO -quit)
        public static void SearchAll()
        {
            _request = Client.SearchAll();                 // or Client.Search("com.unity.cinemachine")
            _deadline = EditorApplication.timeSinceStartup + TimeoutSeconds;
            EditorApplication.update += Poll;
        }

        static void Poll()
        {
            if (_request == null) return;
            if (!_request.IsCompleted)
            {
                if (EditorApplication.timeSinceStartup > _deadline)
                {
                    EditorApplication.update -= Poll;
                    Debug.LogError("[PackageSearch] Timed out.");
                    EditorApplication.Exit(2);
                }
                return;
            }
            EditorApplication.update -= Poll;

            if (_request.Status == StatusCode.Success)
            {
                foreach (var p in _request.Result.OrderBy(p => p.name))
                    Debug.Log($"[PackageSearch] {p.name}@{p.versions.latestCompatible}  {p.displayName}");
                Debug.Log($"[PackageSearch] {_request.Result.Length} packages found.");
                EditorApplication.Exit(0);
            }
            else
            {
                Debug.LogError($"[PackageSearch] Failed: {_request.Error?.message}");
                EditorApplication.Exit(1);
            }
        }
    }
}

_request.ResultはPackageInfo[]です。各エントリーにはname、displayName、description、versions(.latest、.latestCompatible、.all)が公開されています。Editorを使わずにターミナルだけで確認する場合(自由入力の検索ではなく、既知のIDが対象)は、レジストリに直接問い合わせてください。references/select-packages.mdを参照してください。

ヘッドレス実行(-quitなしでEditorを直接起動)

バージョンからEditorのバイナリを特定し、バッチモードで実行します。終了処理はスクリプトがEditorApplication.Exitで行うため、-quitは指定しないでください。

VERSION="<version>"          # e.g. 6000.0.47f1 (or an installed version)
PROJECT="<project-path>"
METHOD="ProjectBootstrap.PackageInstaller.Install"   # or ...PackageSearch.SearchAll

# Install directory of that editor (Hub layout), via the unity CLI
ED=$(unity editors path "$VERSION" --format json | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['path'])")

# Resolve the executable per-OS (handles both "dir containing Unity.app" and the ".app" itself)
case "$(uname)" in
  Darwin) if [ -d "$ED/Unity.app" ]; then UNITY_BIN="$ED/Unity.app/Contents/MacOS/Unity";
          elif [[ "$ED" == *.app ]]; then UNITY_BIN="$ED/Contents/MacOS/Unity";
          else UNITY_BIN="$ED/Unity"; fi ;;
  Linux)  UNITY_BIN="$ED/Editor/Unity" ;;
  *)      UNITY_BIN="$ED/Editor/Unity.exe" ;;   # Windows (Git Bash / MSYS); use Editor\Unity.exe in PowerShell
esac

"$UNITY_BIN" -batchmode -projectPath "$PROJECT" -executeMethod "$METHOD" -logFile -
echo "Exit code: $?"   # 0 = success, 1 = UPM error, 2 = timeout

-logFile -を指定すると、Editorのログ([PackageInstaller] / [PackageSearch]の行を含む)が標準出力にストリーミングされるため、解決の進行状況を確認し、UPMのエラーを読むことができます。ビルドによってunity editors pathの出力形式が異なる場合は、代わりにunity editors --installed --format jsonからディレクトリを取得してください。

検証

# Every requested id should appear as a dependency
cat "<project-path>/Packages/manifest.json"

実行が0で終了したこと、およびリスト内の各パッケージがmanifest.jsonに存在することを確認します。パッケージの解決に失敗した場合は、_request.Error.messageにログが記録されます。内容を読み、ID/バージョンとレジストリを照合してください。-logFile -でストリーミングしたEditor自身のログ([PackageInstaller]の行を含む)は上記の標準出力にあります。unity logsではなく、そちらを確認してください(unity logsに表示されるのはCLI自身のログであり、Editorのログではありません)。

ヘッドレスでインポートして保存する(.meta ファイルを生成する)

スクリプトやツールで新しい .cs/アセットファイルを書き込んだ後、Unity はそれらをインポートして、各アセットに必要な .meta ファイルを生成する必要があります。また、すべての .cs/アセットは、対応する .meta と一緒にコミットする必要があります。プロジェクトを一度開くだけ(unity open "<project-path>")でインポートされ、これらのファイルが生成されます。この処理をヘッドレスで実行する必要がある場合(スクリプトや CI など)は、次の方法を使用してください。

パッケージインストーラーとは異なり、これは同期処理です。処理は戻る前に完了するため、unity run 経由で安全に実行できます(自動挿入される -quit は問題ありません。このメソッドも正常な終了コードを返すために EditorApplication.Exit を呼び出します)。次のファイルを書き込みます。 Assets/Editor/ProjectBootstrap/ProjectSaver.cs:

using UnityEditor;
using UnityEngine;

namespace ProjectBootstrap
{
    public static class ProjectSaver
    {
        // Invoke with: -executeMethod ProjectBootstrap.ProjectSaver.SaveAll
        public static void SaveAll()
        {
            AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate);
            AssetDatabase.SaveAssets();
            Debug.Log("[ProjectSaver] Assets imported and saved.");
            EditorApplication.Exit(0);
        }
    }
}
unity run "<project-path>" --editor-version <version> \
  -- -executeMethod ProjectBootstrap.ProjectSaver.SaveAll

注意事項

  • これらのエディタースクリプトは、ブートストラップを簡便にするためのものです。Assets/Editor/ProjectBootstrap/ に残す(呼び出さない限り何もしません)か、セットアップ後に削除するかは任意です。ユーザーにその旨を伝えてください。
  • すべてのスクリプトは UnityEditor を使用するため Editor/ 以下に置かれており、ビルドに含まれることはありません。
  • マネタイズ/バックエンドのパッケージ(com.unity.purchasing、com.unity.services.levelplay、UGS パッケージ)も同じ仕組みでインストールしますが、実際の統合には専用のスキル、implement-in-app-purchases、levelplay-unity-integration、build-live-gameを使用してください。

コメント