💨 Fusionの[Networked]属性はどう動いている?IL変換と自動同期の仕組みを解剖する
📌 この記事は Zenn に投稿した内容のアーカイブです。 はじめに Photon Fusionは、高性能・高柔軟性なネットワーク同期システムを提供する次世代ネットワークライブラリです。 その中でも特に重要な役割を担っているのが、[Networked] 属性です。 この属性を使うことで、プレイヤーの位置やアニメーション状態、ゲーム内オブジェクトの変化 などを自動的に同期でき、煩雑な手動のデータ送受信処理を省くことができます。 本シリーズでは、Fusionの内部同期処理を段階的に掘り下げて解説していきますが、今回は、[Networked] 属性の裏側で何が起きているのか、どのようにして自動同期が実現されているのかを詳しく見ていきます。 Fusionにおける[Networked]属性の同期処理概要 [Networked] 属性は? Fusionでは、[Networked] 属性が付与されたプロパティはネットワーク状態の同期対象 として扱われますが、ユーザーが手動で同期コードを書く必要はありません。 この仕組みは、Unityが提供する ILPostProcessor API を活用しており、C# で書かれたコードをビルド後にIL(中間言語)レベルで自動変換 しています。 IL ILは、.NET における中間言語です。 Unity では、C# で書いたスクリプトは必ずこの IL を経由してからネイティブコードに変換されます。 具体的には、以下のような処理が行われます: NetworkedWeaved という属性を追加して、該当プロパティがネットワーク状態バッファに割り当てられることを明示 getter/setter が NetworkBehaviour の内部バッファ(StateBuffer)へのメモリアクセスに差し替え られる 実行時に Spawned() されていない場合のアクセス制限も挿入される 変換前のC#コード: [Networked] private Vector2 _position { get; set; } IL変換後(ILSpyで逆コンパイルしたコード): [Networked] [NetworkedWeaved(0, 2)] private unsafe Vector2 _position { get { if (base.Ptr == null) { throw new InvalidOperationException("Error when accessing PhotonCapybara._position. Networked properties can only be accessed when Spawned() has been called."); } return (Vector2)base.Ptr[0]; } set { if (base.Ptr == null) { throw new InvalidOperationException("Error when accessing PhotonCapybara._position. Networked properties can only be accessed when Spawned() has been called."); } Unsafe.Write(base.Ptr + 0, value); } } 補足解説: base.Ptr は NetworkBehaviour に割り当てられたネットワーク状態メモリの先頭ポインタ です。 ...