Unityでのゲーム開発において、開発効率を高めるためにエディタ上での視覚的な補助線(ギズモやハンドル)をスクリプト内に実装することは非常に一般的です。しかし、エディタ上では正常に動作し再生もできていたコードが、いざAndroidやiOS、PCなどの「実機ビルド」を実行した際、The name 'Handles' does not exist in the current contextThe namespace 'UnityEditor' could not be found といったエラーを吐いてビルドが失敗してしまう問題に直面することがあります。

本記事では、このビルド時に発生するエディタ専用コードのコンパイルエラーの根本原因を究明し、実務で安全にエディタ機能と実機コードを切り分けるための解決アプローチを詳細に解説します。

初心者向け:この問題を現実で例えると?

このビルドエラーの問題を、演劇の「舞台裏のリハーサル」と「本番のステージ」に例えてみましょう。

リハーサルの段階(Unityエディタ上)では、監督やキャストが立ち位置を確認するために、ステージの床にバツ印のビニールテープ(ギズモやハンドル表示など)を貼ったり、メガホン(エディタ専用ツール)を使って指示を出したりします。これらはリハーサルをスムーズに進めるために絶対に必要な小道具です。

しかし、いざ劇場の本番公演(実機ビルド)が始まった際、舞台上にバツ印のテープが貼られたままであったり、舞台監督がメガホンを持ってウロウロしていたら客席から大ブーイングが起きてしまいますし、本番の演劇のルール(実機のランタイム環境)にはそんな演出はありません。実機ビルドは「本番の劇」そのものであり、エディタ専用の指示や小道具はすべて片付けられていなければなりません。私たちがやるべきことは、本番中にはこれらのエディタ専用の道具(コード)をきれいに隠す、あるいはあらかじめ楽屋(Editorフォルダ)にしまっておくことです。

不具合の症状と具体的な現象

このビルドエラーが発生した際、以下のような症状が見られます。

  • Unityエディタ上で再生ボタンを押した際は、全くエラーもなく完璧に動作する。
  • File > Build Settings からビルドを実行した途端、コンソールウィンドウに赤いエラーが大量に表示され、ビルドプロセスが強制中断される。
  • エラーメッセージの多くが、UnityEditor 名前空間の using 宣言や、Handles, Gizmos の一部の描画メソッド(例:Handles.DrawWireDiscEditorGUI 関連)を指し示している。

想定される原因:なぜ実機ビルドでエラーになるのか?

Unityエンジンは、ゲームをエディタで動かすための仕組みと、最終的な実行ファイルを書き出すための仕組みでコードベースを分けて管理しています。UnityEditor という名前空間に含まれるすべてのAPIは、Unityエディタ(開発環境)そのものを操作・制御するための機能であり、実機ビルド時にはエンジン側から完全に排除されます。

したがって、ビルドパイプラインが実行される際、実機向けコードのコンパイルプロセスにおいて using UnityEditor;UnityEditor 内のクラスへの参照が残っていると、コンパイラは「そんなクラスや機能は実機用のライブラリには存在しない」と判断し、エラーを発生させます。エディタの親切な補助機能が、ビルド時にはコンパイルの障害になってしまうのです。

具体的な解決方法とアプローチ

この問題を解消するには、主に以下の2つのアプローチがあります。プロジェクトの設計やスクリプトの役割に応じて適切に使い分けましょう。

アプローチ A:プリプロセッサマクロによる条件付きコンパイル

ゲームオブジェクトにアタッチされて実機でも動作するスクリプト内に、エディタ用の補助描画ロジック(例:OnDrawGizmos)を書きたい場合は、#if UNITY_EDITOR#endif を用いてコードを囲みます。これにより、実機ビルド時にはその範囲のコードがコンパイラから完全に無視されるようになります。

using UnityEngine;
// 実機ビルド時に UnityEditor が参照されてエラーになるのを防ぐ
#if UNITY_EDITOR
using UnityEditor;
#endif

public class RangeIndicator : MonoBehaviour
{
    public float detectionRadius = 5.0f;

    // ゲーム中のロジックは実機でも実行される
    void Update()
    {
        // 索敵処理など
    }

    // エディタ上での視覚化処理
    void OnDrawGizmos()
    {
        // Gizmosクラス自体はUnityEngineに含まれるため実機でも呼べるが、
        // HandlesクラスはUnityEditorに含まれるため、マクロで囲む必要がある
        #if UNITY_EDITOR
        Handles.color = Color.green;
        // transformの真上に円を描画
        Handles.DrawWireDisc(transform.position, Vector3.up, detectionRadius);
        #endif
    }
}

アプローチ B:Editorフォルダへの物理的なファイル分離

もし作成したスクリプト自体が、カスタムインスペクター(Editor クラスを継承したもの)や、独自のメニューウィンドウ(EditorWindow)など、100%エディタでしか使わないファイルである場合は、フォルダ構成で制御します。 プロジェクトの Assets フォルダ以下のどこかに 「Editor」 という名前のフォルダ(例:Assets/Scripts/Editor)を作成し、その中にスクリプトファイルを物理的に移動します。Unityは「Editor」という名前のフォルダ内にあるコードを自動的にエディタ専用アセンブリにまとめ、実機ビルドの対象から完全に除外してくれます。

実務で役立つ確認チェックリスト

エディタコード起因のビルドエラーを防ぐための事前チェックリストです。

確認ポイント 対策・ルール
ファイルの配置場所 Editor クラスを継承しているファイルは、すべて Editor という名前のフォルダ内に配置されているか。
using句の確認 using UnityEditor;Editor フォルダ外のスクリプトにある場合、必ず #if UNITY_EDITOR で囲まれているか。
Handles等の使用箇所 通常のスクリプト内の OnDrawGizmosOnDrawGizmosSelectedHandlesEditorGUI を呼び出す際、マクロで囲んでいるか。

まとめ

Unityエディタ用のAPIは開発を非常に快適にしますが、ビルド時のコンパイルプロセスにおいては明確に区別される必要があります。#if UNITY_EDITOR マクロによる部分的な除外と、Editor フォルダによる物理的なアセンブリ分離を正しく理解し、使い分けることで、ビルドエラーを未然に防ぎ、チーム開発でもスムーズなデプロイパイプラインを維持しましょう。