unityでいってみよう!

unityがチョットワカル位の人の娘のブログ

Unity 6000.3.0f1でEditor Assembliesを「.NET Standard」にしたらURPがコンパイルエラーになる件を追いかけてみよう

Unity 6000.3.0f1で「Editor Assemblies Compatibility Level」をお試しで .NET Standard に切り替えたら、URPのEditorコードで System.Runtime.Remoting.Messaging が見つからないエラーが出て、Playモードに入れなくなった……という事例のまとめです。

どの設定を変えると再現するのか、「なんで.NET Standardだとダメなの?」という仕組みの話と、現状取りうるワークアラウンド.NET Frameworkに戻す/URPパッケージをいじる)を、Unity中上級者向けに整理していきます。

1. 導入:.NET Standardに変えたらPlayモードが実行出来ない…?

Unity 6000.3.0f1を触っていて、ふとこんなことを思ったんですよ。

「Editor側の互換性レベルも .NET Standard にしておいた方が、将来的には良さそうじゃない?」

で、Editor Assemblies Compatibility Level を「.NET Framework」から「.NET Standard」に切り替えてみたら……

  • コンパイルが走る

  • Consoleに赤いエラーメッセージ

  • Playボタンが押せない

という、なかなかショッキングな状況に😇

Console を見ると、URPのEditorコードでこんなエラーが出ていました。

Library\PackageCache\com.unity.render-pipelines.universal@d9aadd996b24\Editor\2D\Converter\Base2DMaterialUpgrader.cs(9,31): error CS0234: The type or namespace name 'Messaging' does not exist in the namespace 'System.Runtime.Remoting' (are you missing an assembly reference?)

つまり、

  • System.Runtime.Remoting.Messaging が見つからない

  • そのせいで URP の Editor アセンブリコンパイル失敗

  • 結果として Play モードに入れない

という状態です。

ここからは、

  1. どういう設定で再現するのか

  2. なんで .NET Standard だとこの名前空間がダメなのか

  3. 今できる対処方法

を順番に整理していきます。

2. 再現環境と手順の整理

まずは、現象をもう少しきちんと言葉にしておきます。

■ 動作環境(例)

  • Unity 6000.3.0f1(Unity 6.3 LTS)

  • テンプレート:URP 3D / URP 2D のいずれか

  • URP パッケージ:com.unity.render-pipelines.universal 17.0.4

■ 再現手順

  1. URP テンプレートで新規プロジェクト作成

  2. メニューから Edit > Project Settings… を開く

  3. Player > Other Settings を選択

  4. Configuration セクションにある

    • Editor Assemblies Compatibility Level

    • デフォルトの .NET Framework から “.NET Standard” に変更

  5. スクリプトの再コンパイルが走ったあと、Console を確認&Playボタンを押す

→ 上記の CS0234 エラーが出ており、Playモードに入れない。

「Player 用の API Compatibility Level じゃなくて、Editor Assemblies の方を .NET Standard にしただけ」で再現する、というのがポイントです。

3. Editor Assemblies Compatibility Levelってそもそも何?

まず前提として、この設定が何をコントロールしているかを整理しておきます。

Unity には、似た名前の設定がいくつか存在します:

  • API Compatibility Level(Player用)

    • 実際にビルドされるゲーム本体(プレイヤー)で、どの .NET プロファイルを使うか

  • Editor Assemblies Compatibility Level(Editor用)

    • Editor フォルダ配下や、Editor専用Assembly Definition(include platforms: Editor)など、Editor上で動くコード に対して、どの .NET プロファイルを使うか

今回触っているのは後者の Editor Assemblies Compatibility Level です。ここを .NET Standard にすると:

  • Unityエディタ上で動く C# スクリプト(Editor拡張・カスタムウィンドウ・インポータなど)が

  • .NET Standard 2.1 をターゲットにした世界コンパイル&実行される

ようになります。

URP の Editorコードももちろん「Editor上で動くコード」なので、この影響をモロに受けるわけですね。

4. .NET Standard と System.Runtime.Remoting の関係

じゃあ、なんで「.NET Standardにした瞬間に System.Runtime.Remoting.Messaging が見つからない」のか?

これはざっくり言うと、

.NET Standard / .NET Core 系では、.NET Remoting まわりのAPIはサポート対象から外れている

という歴史的経緯が理由です。

  • .NET Framework 時代には、分散オブジェクト技術として .NET Remoting という仕組みがあり、その中で System.Runtime.Remoting 名前空間と、その配下の Messaging などのクラス群が使われていました。

  • ですが、.NET Core 以降は WCF / Remoting / AppDomain 跨ぎの通信 など、いくつかのレガシー技術が「非推奨&非サポート」扱いになっています。

  • それに合わせて、.NET Standard 2.x でも System.Runtime.Remoting は基本的に含まれていません。

つまり、.NET Standard の世界では、

ので、using System.Runtime.Remoting.Messaging; と書いた瞬間に CS0234 で怒られる、というわけです。

一方で、.NET Framework 4.x 系では今でも System.Runtime.Remoting.Messaging 自体は存在していて、

  • 非同期呼び出しの結果を扱うクラス

  • メッセージングオブジェクト

などを提供しています。

「Editor Assemblies Compatibility Level = .NET Framework」の時は、この名前空間がちゃんとあるのでコンパイルが通る、という仕組みですね。

5. URPのどこで System.Runtime.Remoting.Messaging を使っているの?

エラーメッセージを見ると、問題になっているのは URP パッケージ内のこのファイルです:

Library\PackageCache\com.unity.render-pipelines.universal@d9aadd996b24\Editor\2D\Converter\Base2DMaterialUpgrader.cs

Base2DMaterialUpgrader は名前の通り、2D用のマテリアルをURP用に変換するための Editor拡張クラス です。2D Renderer用の旧マテリアルや設定を、新しいURPパイプライン向けにアップグレードする処理のベースになっているような立ち位置ですね。

このファイルの先頭付近を見ると、

using System.Runtime.Remoting.Messaging;

という1行が含まれています。

  • Editor Assemblies Compatibility Level = .NET Framework のとき:

    • System.Runtime.Remoting.Messaging が存在する → OK

  • Editor Assemblies Compatibility Level = .NET Standard のとき:

という、とてもシンプルな構図です。

実際、海外フォーラムなどでは、

「この using System.Runtime.Remoting.Messaging; 行を削除したらコンパイル通ったよ」

という報告も出ています。

つまり、

  • URP側のEditorコードが “.NET Standard環境では使えないAPI” に依存したまま になっている

のが根本原因、という見立てでほぼ間違いなさそうです。

6. 取りうる対処方法

じゃあ、実際のプロジェクトではどう対処すればいいのか?

ここでは、現実的な選択肢を3つに分けて書いておきます。

6-1. 一番安全:Editor Assemblies Compatibility Level を .NET Framework に戻す

正攻法かつ一番安全なのは、設定を元に戻してしまう パターンです。

■ 手順

  1. Edit > Project Settings… を開く

  2. 左側のツリーから Player を選択

  3. Other Settings タブの中の Configuration セクションにある

    • Editor Assemblies Compatibility Level

    • “.NET Standard” → “.NET Framework に戻す

これだけで、

  • Editor用のコンパイルターゲットが再び .NET Framework になる

  • System.Runtime.Remoting.Messaging も復活

  • URP Editorコードがコンパイルエラーを出さなくなる

という流れになります。

■ メリット

  • URPパッケージをいじらないので、公式サポート的にも一番無難

  • Player側の API Compatibility Level とは独立しているので、

    • Player は引き続き .NET Standard 2.1 を使う

    • Editor だけ .NET Framework のまま

という構成も可能です。

■ デメリット

  • 「Editorも含めて全体的に .NET Standard で揃えたい」という方針とはちょっとズレる。

  • .NET Framework固有のAPI(Remotingなど)に依存したEditor拡張が、今後も普通に動き続けてしまうので、将来的な移行の足枷になる可能性はあります。

とはいえ、今すぐ仕事のプロジェクトを止めないためのワークアラウンドとしては、まずこの方法を検討するのが現実的だと思います。

6-2. 自己責任:URPパッケージをEmbedded化して using 行を削除

もう一歩踏み込んだやり方として、URPパッケージをプロジェクト内に埋め込んで、問題の using 行を削る という方法もあります。

■ 手順のイメージ

  1. Unityエディタ上で、Projectウィンドウの Packages フォルダを右クリックし、Show in Explorer (Macの場合は Reveal in Finder) を選択して、OSのファイルブラウザを開きます。
  2. 開いたウィンドウから、以下のパスへ移動してください。ここには現在プロジェクトにキャッシュされているパッケージが保存されています。

    • パス: [プロジェクトルート]/Library/PackageCache/

    この中に、com.unity.render-pipelines.universal@xxx (xはランダムな文字列)というフォルダがあるはずです。これがURPの実体です。

  3. パッケージを Packages フォルダへコピーする
    1. 上記の com.unity.render-pipelines.universal@... フォルダをコピーします。

    2. プロジェクトのルートにある Packages フォルダ(Libraryと同じ階層にあるフォルダ)へ移動します。

    3. コピーしたフォルダをここに貼り付けます。

  4. 貼り付けたフォルダ名から、バージョン番号(@x.x.x の部分)を削除し、シンプルに com.unity.render-pipelines.universal にリネームします。
  5. Unityエディタに戻ると、自動的にリロード(Re-import)が始まります。完了後、Window > Package Manager を開き、Universal RP パッケージを確認してください。右側の詳細画面で、バージョン番号の横に "Custim" というラベル、またはフォルダアイコンが表示されていれば成功です。これでスクリプトを自由に編集できるようになりました。
  6. プロジェクトビューから、次のファイルを開く:

    Packages/com.unity.render-pipelines.universal/Editor/2D/Converter/Base2DMaterialUpgrader.cs
    
  7. ファイル先頭の using System.Runtime.Remoting.Messaging; 行を削除(またはコメントアウト)する

  8. スクリプト保存 → Unityに戻ってコンパイル完了を待つ

これで、

  • Editor Assemblies Compatibility Level = .NET Standard のまま

  • URP Editorコードから Remoting 依存だけを取り除く

という形になります。

■ メリット

  • Editorも.NET Standardで揃えたまま作業を続行できる。

  • 問題の箇所が「単なるusing行」だけなら、副作用は比較的少なそう。

■ デメリット&注意点

  • 完全に自己責任 になります。

  • 今後 URP パッケージをアップデートしたときに、

    • 上書きされる or 差分マージが必要

  • Unity公式サポートに問い合わせる場合、

    • 「パッケージをローカル編集している状態」はサポート対象外と言われる可能性が高い

なので、本番運用中のタイトルではあまり推奨しづらく、

試験的な環境や、チーム内で事情を共有できている場合の暫定ワークアラウンド

くらいに考えておくのが良さそうです。

6-3. 中長期的にはUnity側の修正版を待つ

今回のケースは、かなりわかりやすい形で

「.NET Standard環境では使えないAPIに、公式パッケージ(URP Editorコード)が依存している」

という状況なので、いずれ Unity 側で修正が入る可能性は高いと思います。

実プロジェクトでこの問題にぶつかっている場合は、

  • Unityの Issue Tracker に類似の報告がないか探す

  • なければ、再現手順を整理したうえで バグレポート を送る

  • フォーラムやディスカッションで、他のユーザーの情報もチェックする

といった動きも合わせて検討するといいかなと。

それまでは、前述の 6-1 or 6-2 のどちらかでやり過ごす、という形になります。

7. まとめ:互換性レベルをいじるときは、パッケージの依存にも注意

最後に、今回のポイントをざっくりまとめておきます。

  • Unity 6000.3.0f1 + URP で、

    • Editor Assemblies Compatibility Level を .NET Standard に変更すると

    • URPの Base2DMaterialUpgrader.csSystem.Runtime.Remoting.Messaging に依存しているせいで

    • CS0234: 'Messaging' does not exist in the namespace 'System.Runtime.Remoting' が発生し、Playモードに入れなくなる

  • .NET Standard / .NET Core 系では、.NET Remoting APIはサポート外のため、

    • System.Runtime.Remoting.* を使うコードは基本NG

  • 対処方法としては:

    1. 一番安全:Editor Assemblies Compatibility Level を .NET Framework に戻す

    2. 自己責任:URPパッケージをEmbedded化して、using System.Runtime.Remoting.Messaging; を削除

    3. 中長期:Unity側の修正版(URPアップデート)を待ちつつ、Issue報告などでフィードバック

Editorまわりの互換性レベルって、「ちょっと上げてみるだけ」のつもりでも、

みたいな Editor拡張の依存関係 を一気に炙り出してくるので、

「変えた瞬間にパッケージのどこが死ぬか」をある程度想定しながら少しずつ試す

のが良さそうだな〜、と今回あらためて実感しました。

同じようにハマった人の参考になればうれしいです!

参考URL

https://discussions.unity.com/t/urp-package-error-in-6-3

https://discussions.unity.com/t/6000-3-0b5-has-permanent-compilation-error-unfixable