ゲームを作成するシーンにおいてエディタを複数起動し同一プロジェクトを操作したくなるシーンがあります。
例えば、オンラインマルチプレイなゲームの開発です。複数のクライアントが必要となるこのケースですが、動作の確認に毎回WebPlayerやStandalone向けにビルドするのも馬鹿らしいので、複数のエディタを立ち上げます。Unityでは本来この手の操作は制限されていますが、この制限を突破する裏ワザを今回紹介します。
やるのは自己責任でお願いします。
ポイントは異なるフォルダと認識させる事
やり方といってもMac版のアプローチは以前に紹介していますので、今回はそのWindows版です。Mac版と比べて若干手抜きが出来ます。さすがはWindows先生だぜ!
要するに、シンボリックリンクを利用し、一つのプロジェクトを複数のフォルダとUnityに認識させれば良い訳です。
WindowsのUnityのプロジェクト判定はRootフォルダのパスで判断しているらしく、Mac版と異なり親フォルダを変えておけば別プロジェクトと認識します。そのため、以下の手順で作成したプロジェクトは、別のプロジェクトと認識させることが出来ます。
プロジェクトフォルダを別Rootのフォルダに作成し*1、そこから「Assets」「ProjectSettings」あと任意で「Library」のシンボリックリンクを作成します。
同一プロジェクトフォルダでUnityエディタ複数起動する手順
今回はベースとなるプロジェクトフォルダが「D:\Unity Project\Unet\uNet Project」にある事を想定して作業を行います。
シンボリックリンクの設定(Windows)
まずはコマンドプロンプト(管理者)を開きます。Windows8の場合はマークを右クリックして、そこから選択します。
コマンドプロンプトのカレントフォルダを移動させます。
cd /d D:\Unity Projects\Unet
新しいフォルダを作り、中に移動します。
この時、元プロジェクトのRoot以下にプロジェクトを絶対作らないようにしてください。プロジェクトが読めなくなります。(たとえばAssetsフォルダと同じ位置に別プロジェクトを作ると、プロジェクトが読めなくなります)
mkdir ”uNet Project Server”
cd "uNet Project Server"
mklink /d Assets "D:\Unity Projects\Unet\uNet Project\Assets"
mklink /d ProjectSettings "D:\Unity Projects\Unet\uNet Project\ProjectSettings"
mklink /d Library "D:\Unity Projects\Unet\uNet Project\Library"
この手順が終わったら、コマンドプロンプトを閉じます。管理者権限が必要なのはここまでで、あまり管理者権限でファイル操作するのは良くないです。
Unityエディタの複数起動
後はUnityを複数起動します。アプローチは二つあります。
一つはコマンドプロンプトから起動する方法です。例えば「"C:\Program Files\Unity\Editor\Unity.exe"」と打てばエディタが起動します。この時管理者権限を持っていると、最悪の場合は起動する度にライセンス入力を要求するようになるかもしれません。
もう1つ目は「Unityのexeを右クリックでコンテキストメニューを開き、Altを押しながら”開く”を選択」する方法です。
エディタを起動したら先ほど作成した「uNet Project Server」のUnityProjectを開くと、別プロジェクトと認識されてますが同じ内容で開けます。
Tempを抜く理由とLibraryの扱い
以前の記事でも書きましたが、Unityが特定のプロジェクトを複数起動できない最大の理由はTempフォルダの存在です。このフォルダは「起動時・終了時に削除される」事が期待されており、この中のファイルはゲーム再生時やビルド時の一時フォルダとして使用されています。
代表的なものは、__EditModeSceneでしょうか。Unityエディタはゲーム再生時に現在のシーン状況を__EditModeSceneに格納し、ゲーム再生終了時に__EditModeSceneを元にシーン再生前に巻き戻しています。つまり、ゲーム再生時にこの情報が書き換えられると、ゲーム終了時にゲーム再生時の情報を巻き戻す事が出来なくなります。
逆を言えば、Tempフォルダが異なる事や、複数クライアントが同一ファイルを勝手に操作しない限り、Unityは複数のクライアントで同一プロジェクトを操作してもたぶん問題無いという事です。
ここで少し注意すべきはLibraryフォルダの存在です。LibraryフォルダはTempとは異なり、長期的なキャッシュを行うフォルダです。このフォルダにも様々なファイルが格納されますが、概ねファイルと対になるので、Assetsが同一ならば共有してもたぶん問題にはなりません。
但し、SwitchPlatformの実行時に中身をゴッソリ書き換えるので、複数のクライアントで各々異なるプラットフォームを使用する場合、Libraryも分ける方が無難でしょう。
逆に、SwitchPlatform前にLibraryの参照先を切り替えたり、他のエディタから裏でLibraryを更新すると、SwitchPlatformの時間がガッツリ減ります(正常に動作するかは未検証ですが)
この辺り、実際はSwitchPlatformが絡む場合はLibraryを別フォルダにするかCacheサーバーを使うのが無難と思われます。もしくはFast Platform Switchでしょうか。
複数エディタ操作時の注意点
最後に複数エディタ操作時の注意点についてです。
まず、複数のエディタを開ける訳ですが、これらのエディタはお互いにインスタンスを共有していません。つまり、エディタAでコピーしたオブジェクトをエディタBにペーストする事は出来ません。またインスタンスが異なるため、エディタAのビューとエディタBのビューを結合といった事も出来ません。
エディタAでシーンを編集し保存した際、編集後の結果は即座にエディタBのシーンに格納されますが、実際に反映するのは下のダイアログでReloadを選択した後です。
これを行わない場合はシーンがコンフリクトする可能性があり、その場合は別シーンとして保存しSceneYamlMergeでコンフリクトを解消する必要が出てくるかもしれません。
プロジェクトの幾つかのファイル、たとえばPrefabやAnimatorが保存されるタイミングは、編集時ではなくProjectやシーンの保存タイミングである事も注意が必要です。Projectを保存するには「メニューバー>Edit>Save Project」から行います。
他に問題点や気づいた点があれば、Twitterもしくは本記事のコメント等で共有してもらえると嬉しいです。
最後に、以前の記事でも書きましたが自己責任でお願いします。
*1:同一Root以下に別フォルダを作成してこの手順を行った場合、最悪プロジェクトが壊れます