こんにちは、Unityエンジニアのオオバです。
Unity 7、試したくなりますよね。
僕も開発中の「勇者のどうぐ屋さん」をUnity 7で動かしています。
その中で困ったのが、Unity CLI Loop(uLoop)が起動しなくなったことでした。
Unity CLI Loopは、UnityをCLIから操作できる外部のOSSツールです。
普段からuLoop経由でコンパイルや確認を回しているので、動かないと作業が止まります。
正直かなり焦りました。
本記事では、uLoopがUnity 7で起動しなかった原因と、僕が実際にやった解決方法をまとめます。
同じエラーで止まっている方の参考になればうれしいです。
コンパイル時と実行時で型の置き場所が食い違っていました。互換レベルは.NET Frameworkのまま、uLoopに型名で生成するパッチを当てて解決
先に結論です。
エラーの原因は、Unity 7アルファ版の参照アセンブリとCoreCLRの食い違いでした。
コンパイル時に参照する System.Core.dll には UnixDomainSocketEndPoint があります。
一方、実行時のCoreCLRの System.Core.dll には、この型がありません。
Editor Assemblies Compatibility Levelを「.NET Standard」に変えると、今度は同梱のHarmonyがコンパイルできなくなります。
そこで互換レベルは「.NET Framework」のままにして、uLoopをローカルでパッチしました。
- 参照アセンブリのSystem.Coreには型があり、実行時のCoreCLRのSystem.Coreには無い
- .NET Standardにすると同梱Harmonyがコンパイルエラーになる
- UnixDomainSocketEndPointをSystem.Net.Socketsから型名で引いて生成すれば動く
- コンパイルエラーが1つでも残るとUnityは新しいアセンブリをロードしない
起きたこと
環境は次のとおりです。
- Unity 7000.0.0a8
- Unity CLI Loop 3.2.1
- macOS 15.4.1(Apple Silicon)
Unity 7000.0.0a8で、uLoopのサーバーが起動しませんでした。
エラー文はこちらです。
Server startup failed: Failed to start server: Could not load type 'System.Net.Sockets.UnixDomainSocketEndPoint' from assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'.
起動直後の自動復帰も「project IPC endpoint could not be bound within 5000ms」で失敗します。
uloop コマンドを叩いても応答が無く、タイムアウトするだけでした。
原因:参照アセンブリとCoreCLRで型の置き場所が違う
最初に引っかかったのは、uLoopの配布形態です。
uLoopはパッケージのソースをUnityがコンパイルしています。
DLLを同梱する形のパッケージなら、ビルド環境の違いを疑うところです。
ところがuLoopは手元のUnityでコンパイルされているのに、実行時に「System.Coreから型を読めない」と言われます。
コンパイルは通る。
それでも実行時には型が見つからない。
となると、コンパイル時と実行時で見ているアセンブリが違うはずです。
コンパイル時は.NET Framework 4.8互換の参照を見ている
Editor用のアセンブリは、Editor Assemblies Compatibility Levelが「Default」のとき、.NET Framework 4.8互換でコンパイルされます。
コンパイラ引数には -define:NET_4_6 や NET_UNITY_4_8 が付いていて、参照先は UnityReferenceAssemblies/unity-4.8-api/ でした。
アセンブリごとの型の有無
型がどこにあるかを、アセンブリごとに確かめた結果がこちらです。
| アセンブリ | 場所 | 型の有無 |
|---|---|---|
| System.Core.dll | 参照側(unity-4.8-api/) | ある |
| System.Core.dll | 実行側(Scripting/CoreCLR/lib/) | 無い |
| System.Net.Sockets.dll | 実行側(Scripting/CoreCLR/lib/) | ある(実体) |
| netstandard.dll | 参照側(unity-4.8-api/Facades/) | ある |
| netstandard.dll | 実行側(Scripting/CoreCLR/lib/) | ある |
参照側の System.Core.dll に型があるのは、Mono時代の配置の名残です。
実行側の System.Core.dll は12KBほどの転送用ファサードで、UnixDomainSocketEndPoint は含まれていません。
実体は System.Net.Sockets.dll にあります。
そのため、コンパイル結果は「System.CoreにあるUnixDomainSocketEndPoint」を参照します。
実行時にCoreCLRのSystem.Coreを見に行くと型が無く、TypeLoadになるわけです。
uLoopのコード自体は普通の書き方です。
原因はUnity 7アルファ版の参照アセンブリとCoreCLRの組み合わせにありました。
調べ方
型の有無は、DLLのバイト列に型名が含まれるかをPythonで見て確かめました。
EditorAssembliesCompatibilityLevel の数値は、XMLドキュメントに載っていません。
そこで uv run --with dnfile で UnityEditor.CoreModule.dll のメタデータから読みました。
- Default = 1
- NET_Unity_4_8 = 2
- NET_Standard = 3
.NET Standardにしたら別の壁
最初に試したのは、互換レベルを.NET Standardにする方法です。
Project Settings > Player > Other Settings > Editor Assemblies Compatibility Levelを「.NET Standard」に変えます。
ProjectSettings.asset では editorAssembliesCompatibilityLevel: 3 になります。
参照も実行も netstandard.dll 経由になるので、食い違いは起きないはず。
そう考えて切り替えたところ、今度はuLoopの一部がコンパイルできなくなりました。
HotReloadPatcher.cs(437,43): error CS7069: Reference to type 'ILGenerator' claims it is defined in 'mscorlib', but it could not be found
SourcePausePointInjectionEmitter.cs(71,28): error CS7069: Reference to type 'Label' claims it is defined in 'mscorlib', but it could not be found
同梱のHarmonyが.NET Framework向けだった
uLoopには UnityCliLoop.0Harmony.dll が同梱されています。
このHarmonyは.NET Framework向けにビルドされていて、System.Reflection.Emit の型を mscorlib にある前提で参照しています。
.NET Standard 2.1の参照セットでは、mscorlibからたどれません。
エラーの出る場所が原因から遠い
やっかいなのは、ここからの連鎖です。
HotReload / PausePointのアセンブリがビルドされない。
すると、それに依存する UnityCLILoop.CompositionRoot.Editor もビルドされない。
結果として、[InitializeOnLoadMethod] の起動処理が丸ごと存在しない状態になりました。
表示されたエラーは「Unity CLI Loop server application service is not registered.」です。
原因のコンパイルエラーから遠い場所で落ちるので、かなり分かりにくいですよね。
Library/ScriptAssemblies/ にCompositionRootのDLLが無いのを見て、ようやく気付きました。
板挟みの状態
ここまでで、互換レベルはどちらを選んでも詰む状態になりました。
- .NET Framework(Default): コンパイルは通る。実行時にUnixDomainSocketEndPointが見つからない
- .NET Standard: Harmony由来の型解決でコンパイルが通らない
uLoopの最新版(3.14.0、2026-10-07)も確認しました。
最新版も new UnixDomainSocketEndPoint(...) を直接使っているので、バージョンを上げても解決しません。
解決:.NET Frameworkに戻してuLoopをローカルパッチ
Unity 7の互換レベルの選択肢は「.NET Framework」と「.NET Standard」の2つでした。
「Default」という項目はありません。
中身のenumにはDefault = 1が残っています。
互換レベルは.NET Frameworkに戻しました。
その上で、uLoop側の生成処理を書き換えます。
uLoopを埋め込みパッケージにする
uLoopを Packages/io.github.hatayama.uloopmcp に置いて、埋め込みパッケージにしました。
埋め込みパッケージは、レジストリ版より優先されます。
レジストリ版を消さなくても、手元のコードを編集できる状態になります。
UnixDomainSocketEndPointを型名で引いて生成する
UnixDomainSocketEndPoint を作っている箇所は2か所でした。
どちらも次の形に置き換えています。
internal static EndPoint Create(string path)
{
#if UNITY_7000_0_OR_NEWER
// コンパイル時に型を直接書くと System.Core 参照になり、実行時に解決できないため、型名で引く
Type endPointType = typeof(Socket).Assembly.GetType("System.Net.Sockets.UnixDomainSocketEndPoint", throwOnError: true);
return (EndPoint)Activator.CreateInstance(endPointType, path);
#else
return new UnixDomainSocketEndPoint(path);
#endif
}
ポイントは typeof(Socket).Assembly です。
Socket は実行時に System.Net.Sockets.dll から読み込まれます。
UnixDomainSocketEndPoint の実体も同じアセンブリにあるので、そこから型名で引けば確実に見つかります。
コードに型を直接書くと、コンパイル結果はSystem.Coreを参照してしまいます。
型名の文字列で引くことで、コンパイル時の参照先を経由せずに済むわけです。
UNITY_7000_0_OR_NEWER で分けているので、Unity 6以前では元のコードのまま動きます。
ハマりどころ:コンパイルエラーが残ると新しいアセンブリがロードされない
パッチを当てたあとも、エラーは「not registered」のままでした。
「え、直したのに?」
と、ここが一番時間を溶かしたところです。
原因は、プロジェクトのどこかにコンパイルエラーが1つでも残っていると、Unityは新しいアセンブリをロードしないことでした。
ドメインリロードが走らないので、古いアセンブリのまま動き続けます。
uLoop自体は直っていました。
それでも、SRDebuggerとテストコードのエラーが残っていたので、古いuLoopが動いていたわけです。
全部のエラーを直して Tundra build success → Reloading assemblies がログに出た瞬間、uloopが応答しました。
外部ライブラリが通ると自作コードのエラーが見えてくる
もう1つ、副産物があります。
外部ライブラリのコンパイルが通ったことで、初めて自作コード側のエラーが見えました。
LayoutGroup.SetLayoutInputForAxisの引数追加GetInstanceID
Unityのコンパイルはアセンブリ単位です。
依存元のアセンブリが落ちていると、下流のエラーは出てきません。
1つ直すと次のエラーが出てくるので、Unity 7への移行では「エラーが減らない」と感じる場面が続くと思います。
uLoopが使えない間のコンパイルの回し方
uLoopが動かない間は、CLIからコンパイルを指示できません。
僕は次の方法でコンパイルを回していました。
osascriptでUnity 7のウィンドウを前面に出し、自動リフレッシュを走らせるLogs/Editor.logのTundra build success/Tundra build failedとerror CSを見て結果を確認する
地味ですが、ログを見れば結果は追えます。
まとめ
Unity 7でuLoopが起動しない原因は、参照アセンブリと実行時のCoreCLRで UnixDomainSocketEndPoint の置き場所が違うことでした。
- コンパイル時の
System.Core.dll(unity-4.8-api)には型がある - 実行時のCoreCLRの
System.Core.dllには型が無く、実体はSystem.Net.Sockets.dll - 互換レベルを.NET Standardにすると、同梱のHarmonyがコンパイルできない
- 互換レベルは.NET Frameworkのまま、
typeof(Socket).Assemblyから型名で引いて生成すれば動く - コンパイルエラーが1つでも残っていると、新しいアセンブリはロードされない
エラー文だけ見ると「uLoopが壊れた?」と思ってしまいます。
実際は、Unity 7アルファ版のランタイムの切り替えで生まれた隙間に落ちただけでした。
今回の対処はローカルパッチなので、uLoopを更新したら当て直しが必要です。
Unity 7の正式版で参照アセンブリ側が直れば、パッチ自体が要らなくなるかもしれません。
同じようにUnity 7でTypeLoad系のエラーに当たった方は、参照側と実行側のDLLに型があるかを見比べてみてください。

筆者のXをフォローしよう
- Unity7000.0.0a8
- Unity CLI Loop 3.2.1
- macOS 15.4.1 (Apple Silicon)







