こんにちは、Unityエンジニアのオオバです。

お悩みさん
お悩みさん
  • UnityをCLIから操作したい
  • unity pipeline installが失敗する
  • HotReloadが効かない
  • オオバ
    オオバ
    本記事ではこれらの悩みを解決します。

    Unity公式がスタンドアロンのCLIツール「Unity CLI」を提供し始めたのをご存知でしょうか。

    さらに実験的パッケージ 「Unity Pipeline」 を組み合わせると、起動中のUnityエディターをターミナルからHTTP経由で遠隔操作できるようになります。

    再コンパイル、テスト実行、スクリーンショット、任意のC#実行、そしてホットリロードまで、約140個のコマンドが使えます。

    AIエージェントにUnityを触らせる文脈で、間違いなく本命になっていく仕組みだと思います。

    ただ、実際に導入してみたところいくつもの罠にハマりました。

    本記事では僕が実際にハマった実体験をベースに、準備〜始め方、そして注意点までまとめて解説します。

    これから触る方はぜひ最後まで読んでみてください。

    Unity CLIとUnity Pipelineとは

    まず用語を整理します。

    Unity CLI は、エディターのインストール、モジュール管理、プロジェクト管理などをターミナルから行える公式CLIツールです。Unity Hubのコマンドライン版と考えると分かりやすいです。

    Unity Pipeline(com.unity.pipeline)は、プロジェクトに追加する実験的パッケージです。エディター内にローカルHTTPサーバーを立て、CLIからのコマンドを受け付けます。

    つまり構図はこうです。

    Unity CLI(ターミナル側) ←HTTP→ Unity Pipeline(エディター側サーバー)  
    

    サーバーのバインドは127.0.0.1のみ、Bearer認証付きなので、外部からは触れない設計になっています。

    なお、Unity Pipelineは Unity 6.0以降 のプロジェクトで動作します。

    準備:Unity CLIのインストール

    まだUnity CLIを入れていない場合は、公式のインストールスクリプトで導入します。

    # macOS / Linux
    curl -fsSL https://public-cdn.cloud.unity3d.com/hub/prod/cli/install.sh | UNITY_CLI_CHANNEL=beta bash  
    

    インストール後にターミナルを開き直し、サインインします。

    unity auth login  
    

    【罠1】CLIが古いと pipeline コマンドが存在しない

    ここで1つ目の罠です。

    僕の環境には以前入れたUnity CLI(v0.1.0-beta.3)があったのですが、このバージョンには pipelineコマンド自体が存在しません。

    しかも unity upgrade --check を実行しても「更新あり」とは教えてくれませんでした。

    以下のコマンドでbetaチャンネルを明示してアップグレードしたところ、v1.0.0-beta.2に更新されてpipelineコマンドが使えるようになりました。

    unity upgrade --channel beta -y  
    

    unity pipeline --help が通れば準備OKです。

    【罠2】コマンドの語順を間違えると謎エラー

    2つ目の罠は完全に僕のミスなのですが、共有する価値があると思うので書きます。

    正しいコマンドはこちら。

    unity pipeline install  
    

    僕は最初こう打っていました。

    unity install pipeline  
    

    すると 「指定したエディターバージョンは既知の Unity Editor バージョンと一致しません」 というエラーが出ます。

    実は unity install の第1引数はエディターのバージョン番号なんです。

    つまり「pipelineというバージョンのUnityエディターをインストールしろ」と解釈されていたわけです。

    エラーメッセージだけ見ると意味不明ですが、原因はただの語順ミス。同じエラーで悩んでいる方は打ったコマンドを見直してみてください。

    始め方:Unity Pipelineの導入

    ここからが本番です。

    対象のUnityプロジェクトをエディターで開いた状態にして、プロジェクト直下のターミナルで実行します。

    unity pipeline install  
    

    これで com.unity.pipeline パッケージが Packages/manifest.json に追加されます。

    エディターにフォーカスを当てて再コンパイル

    ここで注意点。

    manifest.jsonが書き換わっただけでは、起動中のエディターはパッケージを取り込みません。

    一度Unityエディターにフォーカスを移して、パッケージ解決と再コンパイルを走らせてください。

    完了すると、エディター内でPipelineのHTTPサーバーが自動起動します。

    接続確認

    以下のコマンドで状態を確認できます。

    unity pipeline list  
    

    Server Reachabletrue になっていれば接続成功です。

    試しにエディターの状態を取ってみましょう。

    unity command editor_status  
    
    {"status":"ready","compiling":false,"playMode":"stopped",...}  
    

    こんなレスポンスが返ってきたら、もうターミナルからエディターを操作できる状態です。

    unity command を引数なしで実行すると、使えるコマンド一覧がズラッと表示されます。僕の環境では141個ありました。

    再コンパイル、テスト実行、GameObject操作、スクリーンショット、C#の動的実行(eval)など、かなり幅広いです。

    ホットリロードを使ってみる

    Unity Pipelineの目玉機能の1つがホットリロードです。

    Play Modeを止めずに、メソッドの中身だけを差し替えられます。

    使い方はシンプルで、差し替えたいメソッドに [HotReload] 属性を付けます。

    using Unity.Pipeline.HotReload;  
    using UnityEngine;  
    
    public class Spinner : MonoBehaviour  
    {
        public float speed = 90f;  
    
        [HotReload]  
        public void Update()  
        {
            transform.Rotate(Vector3.up, speed * Time.deltaTime);  
        }
    }
    

    一度普通にコンパイルした後、Play Mode中にメソッドの中身を編集して保存し、ターミナルから実行します。

    unity command reload_file --filename "$(pwd)/Assets/Spinner.cs"  
    

    これでドメインリロードなしに、実行中の挙動が変わります。

    ……と、ここまでがドキュメント通りの説明なのですが、実際にはここからが罠の本番でした。

    注意点:HotReloadでハマった3つの罠

    【罠3】保存しただけでは何も起きない。フォーカスするとドメインリロード

    僕は最初 「保存したら自動でホットリロードされる」 と思い込んでいました。

    アセットストアの有名アセット「Hot Reload」がそういう挙動だからです。

    しかしUnity Pipelineのホットリロードは、reload_fileコマンドを明示的に叩いたときだけ差し替えが起こります。

    さらに悪いことに、ファイル保存後にUnityエディターへフォーカスを移すと、Auto Refreshが走って普通の再コンパイル+ドメインリロードになってしまいます。

    「HotReload属性を付けたのにドメインリロードが入る」と感じたら、だいたいこれが原因です。

    正しいワークフローはこうです。

    1. [HotReload] を付けて一度普通にコンパイル(初回のみドメインリロード必須)
    2. Play Mode中にメソッド本体を編集して保存
    3. Unityにフォーカスを移さず、ターミナルから reload_file を実行

    【罠4】publicメンバーにしかアクセスできない

    reload_fileを実行したら、今度はこんなエラーが出ました。

    Cannot access non-public member '_dir' in [HotReload] method 'Hoge'  
    

    差し替え後のメソッド本体は別アセンブリとしてコンパイルされ、元のアセンブリの隣にロードされます。

    このため、元クラスのpublicメンバーにしかアクセスできません。

    privateフィールドやprivateメソッドを触っているメソッドに [HotReload] を付けると、検証で弾かれます。

    普段の規約的には気持ち悪いですが、検証用コードならpublic化してしまうのが最短です。

    ほかにも制約があります。

    制約内容
    メソッドvoidを返すインスタンスメソッドのみ
    static不可(コンパイル時に警告付きでスキップ)
    戻り値あり不可(同上)
    環境Editor Play Mode / Monoのdevelopmentビルドのみ
    IL2CPP不可

    【罠5】successなのに差し替わらない「with 0 methods」問題

    ここが本記事で一番伝えたいところです。

    罠3と罠4をクリアしてreload_fileを実行したところ、こんな結果が返ってきました。

    In-place hot reload successful: InPlace_Test_xxx with 0 methods  
    

    successなのに、画面の挙動は何も変わりません。

    注目すべきは 「with 0 methods」 の部分。コンパイルは成功したけど、差し替え対象として0件しか登録されていないという意味です。

    パッケージのソースを追った結果、原因は com.unity.pipeline 0.3.1-exp.1 の実装漏れと思われる挙動でした。

    つまりエディターのPlay Modeでは、[HotReload] を付けたメソッドが誰にも登録されず、差し替えが全件スキップされるのです。

    Editor.logには実際に警告が出ていました。

    HotReload: Target method 'Test.Update' not found or not marked [HotReloadWithOverrides]  
    
    ※実験的パッケージ(-exp)なので、今後のバージョンで修正される可能性が高いです

    回避策:evalで手動登録する

    回避策はあります。Unity Pipelineには任意のC#を実行できる eval コマンドがあるので、これでレジストリに手動登録します。

    Play Mode中に一度だけ、以下を実行してください(Test の部分は自分のクラス名に置き換え)。

    unity command eval --code 'var flags = System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.DeclaredOnly; int n = 0; foreach (var m in typeof(Test).GetMethods(flags)) { if (System.Attribute.IsDefined(m, typeof(Unity.Pipeline.HotReload.HotReloadAttribute))) { Unity.Pipeline.HotReload.HotReloadRegistry.RegisterReloadableMethod(m, new Unity.Pipeline.HotReload.HotReloadWithOverridesAttribute()); n++; } } return "registered " + n + " methods";'  
    

    これを実行した後にreload_fileを叩くと、僕の環境では 「with 3 methods」 に変わり、ドメインリロードなしで挙動が差し替わることを確認できました。

    移動速度を1→8倍に書き換えたら、Play Modeを止めずにオブジェクトの動きが一瞬で変わります。この体験はかなり感動しました。

    注意点として、レジストリはstaticなのでPlay Modeを入り直す(=ドメインリロードが走る)たびに再登録が必要です。

    まとめ

    Unity CLI + Unity Pipelineの導入手順と注意点をまとめます。

    準備〜始め方

    1. Unity CLIをインストール(既存の人は unity upgrade --channel beta -y で更新)
    2. unity auth login でサインイン
    3. プロジェクトを開いた状態で unity pipeline install
    4. エディターにフォーカスして再コンパイル
    5. unity pipeline list で Server Reachable が true なら接続完了

    注意点

    実験的パッケージだけあって粗さは残っていますが、ターミナルからUnityエディターを完全制御できるインパクトは相当なものです。

    特にAIエージェントにUnity開発をさせたい人にとっては、公式がこの方向に舵を切ったこと自体が大きなニュースだと思います。

    僕も引き続き検証して、実運用に耐えるかを見極めていきます。

    Unityの学習、1人で進めるのは大変ですよね。この度、AIと一緒にUnityゲームを開発する方法をまとめた「AI×Unityゲーム開発スターターキット」を執筆しました。

    AI時代のゲーム開発を先取りしたい方はぜひ確認してみてください! → AI×Unityゲーム開発スターターキット

    最後まで読んでいただきありがとうございました!
    すばらしいゲーム開発ライフをお過ごしください。

    オススメ記事
    検証環境
    参考サイト