このページは編集中です。更新が保留になっている可能性があります。

Network Object

はじめに

NetworkObjectGameObjectにネットワークIDを割り当て、ネットワーク上で共有できるようにします。すべてのプレイヤーが見ることができ、シーンの動的な部分であるGameObjectには、NetworkObjectスクリプトを設定します。

Fusionには、カスタムのネットワーク動作を派生させるための2つのNetworkObjectベースクラスがあります。

  • シミュレーション関連の動作にはSimulationBehaviour、そして
  • NetworkBehaviourは、[Networked]の状態を維持または追跡する動作のためです。

トップに戻る

NetworkObject

GameObjectのルートノードに1つのNetworkObjectスクリプトを置くだけで、階層全体を制御することができます。ランタイム時には、NetworkObjectはその階層にあるすべてのSimulationBehaviourNetworkBehaviourを検出します。

必要に応じて、NetworkObjectをネストすることができます。この場合、NetworkObjectはネストした子の中は検索せず、子のNetworkObjectにその下のすべてのSimulationBehaviourNetworkBehaviourを追跡させます。典型的な使用例としては、2人のプレイヤーが操作するシャーシと砲台からなる戦車で、ドライバーがシャーシの方向(移動)を制御し、ガンナーが砲台(射撃)を制御するというものがあります。

トップに戻る

プレハブ/オブジェクトテーブル

PrefabパラメータがFusionにとって意味のあるものであるためには(そして、すべてのクライアントがどのプレハブであるかを正確に把握するには)、プレハブ自体がFusionに登録されている必要があります。通常であれば、Fusionツールセットが自動的にプレハブを検出して登録しますが、NetworkProjectConfigを選択して、Unity InspectorのRebuild Object Tableを押すことで、手動で検出することもできます。

トップに戻る

インスタンス化/スポーン化

NetworkObjectプレハブのインスタンス化には2つのステップがあります。

  1. 編集時: クライアントの NetworkProjectConfig アセットが同一で、NetworkObject プレハブの ID が一致していることを確認します。これは NetworkProjectConfig アセットで Rebuild Object Table を実行することで行います。
  2. ランタイム では、NetworkRunnerSpawn()を、NetworkObjectプレハブをパラメータとして呼び出します。

重要: 一般的なUnityのInstantiate()メソッドを呼び出すと、壊れたローカルインスタンスが作成されてしまいます!

トップに戻る

破壊 / デスポーン

NetworkObjectを破壊するには、Runner.Despawn()を呼び出し、パラメータとしてオブジェクトを渡します。一番上のオブジェクトだけをデスポーンするには、まずネストしたオブジェクトを手動でペアレント解除する必要があります。

DestroyWhenStateAuthorityLeaves

共有モードのみ StateAuthority Playerがゲームから離れた時に、このNetworkObjectが自動的にデスポーンされるかどうかを示します。

トップに戻る

HasStateAuthority プロパティ

HasStateAuthorityプロパティは、SharedモードとServer/Clientモードの両方で有効で、次の場合にtrueを返します。 - Server/Client モード; Runner.IsServer が true。 - Shared Mode; StateAuthority == Runner.LocalPlayer.

このプロパティは、スクリプトで使用して、この NetworkObject の権威あるインスタンスであるかどうかを判断します。

トップに戻る

StateAuthority プロパティ

State Authority は、どの PlayerRef のピアが NetworkObject の状態 (Networked Properties) の最終的な権威であるかを示し、その Networked Property の値は Tick Snapshots として他のクライアントに複製されます。

_ 注意:_ StateAuthority プロパティは Shared Mode にのみ適用されます。Server/Clientモードでは、この値は常にPlayerRef.Noneとなります。Server/Hostピアは常にState Authorityとして機能するためです。

トップに戻る

State Authorityの変更

Server/Clientモードの場合: State Authorityは常にHost/Serverに属しており、移譲することはできません。StateAuthorityは常にPlayerRef.Noneとなります。

共有モード: プレイヤーは、NetworkObjectに対するState Authorityを持ちます(Photon共有サーバは、NetworkObjectのState Authorityを管理しますが、それらのオブジェクトに対するState Authorityは持ちません)。

クライアントから Object.RequestStateAuthority() を呼び出すと、PlayerRefNetworkObject の State Authority として割り当てることができます。Photon Shared Server は、以下の場合にのみリクエストを許可します。 - Object が AllowStateAuthorityOverride を有効にしている場合。 - Object に現在の State Authority がない場合。

AllowStateAuthorityOverride が有効になっておらず、すでにState Authorityが割り当てられている場合、リクエストは無視されます。現在のState Authority Playerは、まずそのクライアントで Object.ReleaseStateAuthority() を呼び出してObjectを解放する必要があります。

トップに戻る

AllowStateAuthorityOverride

共有モードのみ適用 他のプレイヤーが現在StateAuthorityである場合に、そのプレイヤーがStateAuthorityを取得できるかどうかを示します。falseの場合、現在のState Authorityは最初に ReleaseStateAuthority() を呼び出すか、接続を切断しなければなりません。ほとんどのユースケースでは、プレハブやシーンオブジェクトに対して AllowStateAuthorityOverride を有効にしておくとよいでしょう。

このプロパティはspawn前に設定する必要があり、spawn後に変更することはできません。

トップに戻る

HasInputAuthority プロパティ

HasInputAuthority プロパティは Runner.LocalPlayer == Object.InputAuthority の場合、true を返します。スクリプトで、NetworkRunner.LocalPlayerNetworkObject の入力機関であるかどうかをテストするために使用します。

注意: Input Authorityと Fusion の INetworkInput 処理は、主に Server/Client Mode での使用を想定しています。クライアントの予測や再シミュレーションの基礎となるものだからです。しかし、Shared Modeでは、ユーザーの入力はすぐにState Authorityによって消費されるため、INetworkStruct入力システムは必要ありません。しかし、将来的にサーバー/クライアントモードへの移行を考えていて、後々のリファクタリングを避けたい場合は、Shared ModeでもFusion入力システムを使用することができます。

トップに戻る

InputAuthority プロパティ

InputAuthority プロパティは、この NetworkObjectFixedUpdateNetwork において GetInput() が呼ばれたときに、どの PlayerRef の入力データ (INetworkInput) が返されるかを示すものです。プレイヤー入力は、Input Authorityを持つクライアントと、State Authorityを持っているクライアントのみが利用できます。その他のクライアント(Proxy)は GetInput() が呼び出されると false を返します。

Input Authorityの変更

In Shared Mode: INetworkInput の取り扱いは、Shared Mode ではオプションです。しかし、この場合、現在の StateAuthority のみが InputAuthority を変更でき、 Object.AssignInputAuthority() メソッドを使用して変更することが可能です。

Input AuthorityはState Authorityと一致するか、PlayerRef.Noneである必要があります。Input Authorityは StateAuthority の変更に伴って自動的に変更されないので、このような場合は必要に応じて InputAuthority を変更するようにしてください。

public class StateAuthChangeExample : NetworkBehaviour, IStateAuthorityChanged
{
  void IStateAuthorityChanged.StateAuthorityChanged() {
    // If this object is using Fusion Inputs, the new State Authority
    // should acquire Input Authority when it gets State Authority.
    if (Object.HasStateAuthority) {
      Object.AssignInputAuthority(Object.StateAuthority.PlayerId);
    }
  }
}

In Server/Client Mode: InputAuthority PlayerRef は Server 上で Object.AssignInputAuthority() メソッドによってのみ変更することができます。

トップに戻る

SimulationBehaviour

すべての SimulationBehaviour は、Object プロパティを使って、関連する NetworkObject にアクセスできます。

Simulation は、Fusionでネットワークの状態を更新する方法です。シミュレーションの一部であったり、シミュレーションの状態に影響を与える動作は、MonoBehaviourではなく、SimulationBehaviourから派生しなければなりません。

例えば、TanksサンプルのLevelManagerはパワーアップを産み出します。パワーアップはNetworkObjectですが、LevelManagerはシミュレーションの状態に影響を与え、それを知るだけでその動作を実行できます。したがって、SimulationBehaviourを継承するのが正しい方法です。

public class LevelManager : SimulationBehaviour
{
    [SerializeField] private float _powerupDelay;
    [SerializeField] private NetworkObject _powerupPrefab;

    private TickTimer _powerupTimer;

    public override void FixedUpdateNetwork()
    {
        // All of the level management logic happens server-side, so bail if we're not the server.
        if (!Object.HasStateAuthority) return;

        // Only active duty of the LevelManager is to spawn powerups whenever the timer expires
        if (_powerupTimer.ExpiredOrNotRunning(Runner))
        {
            // Reset timer, and check if there is a free spot to spawn a new powerup
            _powerupTimer = TickTimer.CreateFromSeconds(Runner,_powerupDelay);
            SpawnPoint spawnPoint = GetSpawnPoint(SpawnPoint.Type.Powerup);

            if (spawnPoint != null)
            {
                Debug.Log("Spawning Powerup");
                NetworkObject powerupobj = Runner.Spawn(_powerupPrefab, spawnPoint.transform.position, spawnPoint.transform.rotation, PlayerRef.None);
                powerupobj.GetComponent<Powerup>().Init();
            }
            else
            {
                Debug.Log("Not Spawning Powerup - no free spot");
            }
        }
    }
}

動作が [Networked] プロパティへのアクセスを必要とする場合は、代わりに NetworkBehaviour を派生させる必要があります。

トップに戻る

NetworkBehaviour

NetworkBehaviourは、同じノードまたは親ノード上のNetworkObjectを必要とします。

NetworkBehaviourSimulationBehaviourであり、同期した状態を保持することができます。そのため、関連するNetworkObjectを持たなければありません。

トップに戻る

Networked Property

内部的には、Fusion は各 tick のネットワーク状態全体を、Snapshot と呼ばれる一つのメモリバ ッファーとして保存しています。Networked Propertyは、NetworkedBehaviour に含まれるどの変数がそのネットワー ク状態に含まれるかを定義します。

Networked Property を定義するには、[Networked] 属性を使用します。Fusion はこれらのタグ付けされたプロパティを独自の高性能データバッファとデルタ圧縮に自動的に接続します。 プロパティのセッターとゲッターは、コンパイル時にカスタムコードに置き換えられ、メモリ割り当てのオーバーヘッドを排除し、最適なパフォーマンスを提供します。

public class PlayerBehaviour : NetworkedBehaviour
{
  [Networked] public float Health { get; set; }
}

コンパイル時に、Fusionは空のget/setスタブを実際のネットワーク状態データにアクセスするコードに置き換えます。直接アクセスすることで、メモリ割り当てのオーバーヘッドをなくし、最適なパフォーマンスを提供します。手動では実装 しないでください。

このように状態バッファに直接アクセスすることで、変更があるとすぐに状態 に反映されます。

ネットワーク状態に影響するロジックを書くには、FixedUpdateNetwork()をオー バーライドして実装してください。

public override void FixedUpdateNetwork()
{
    Health += Runner.DeltaTime * HealthRegen;
}

トップに戻る

許容される型

  • プリミティブ
    • byte, sbyte
    • Int16, Int32, Int64
    • UInt16, UInt32, UInt64
    • float
    • double
    • float
    • double
    • bool (convereted to int)
  • 最大長 Length を持つ文字列は [Capacity] 属性を用いて設定します(デフォルトは 16 )。
  • Unity 構造体タイプ (ILWeaver.cs で定義)
    • Vector2, Vector3, Vector4
    • Quaternion
    • Matrix4x4
    • Vector2Int, Vector3Int
    • BoundingSphere
    • Bounds
    • Rect
    • BoundsInt
    • RectInt
    • Color, Color32
  • System.Guid
  • ユーザー定義INetworkStructs
  • Fusion 定義 INetworkStructs
    • NetworkString<IFixedStorage>
    • NetworkBool
    • Ptr
    • Angle
    • BitSet64, BitSet128, BitSet192, BitSet256
    • PlayerRefSet
    • NetworkId
    • NetworkButtons
    • NetworkRNG
    • NetworkObjectGuid
    • NetworkPrefabRef
    • NetworkObjectHeader
    • NetworkPrefabId
    • SceneRef
    • TickTimer
    • IFixedStorage (_2, _4, _8, _16, _32, _64, _128, _256, _512) -Fusion 型
    • NetworkObject (NetworkId として直列化される)
    • NetworkBehaviour (NetworkIdNetworkBehaviour インデックスとして直列化される)
    • PlayerRef (PlayerRef.PlayerId として直列化される)
  • NetworkArray<T> 最大長 Length を持つ文字列は [Capacity] 属性を用いて設定します(デフォルトは 1 )。
  • NetworkDictionary<K, V> 最大値 Count を持つものは [Capacity] を使って設定します。
  • NetworkLinkedList<T> 最大値 Count を持つものは [Capacity] を使って設定します。

トップに戻る

Accuracy属性

[Accuracy]属性を用いることで、個々の数値型プロパティの精度を制御することができます。

public class PlayerBehaviour : NetworkedBehaviour
{
  [Networked, Accuracy(0.001)]
  public float Health { get; set; }
}

トップに戻る

Capacity属性

NetworkArray<T>, NetworkDictionary<K, V>, NetworkLinkedList<T>と文字列の最大サイズを定義するために使用されます。

public class MyNetworkBehaviour : NetworkedBehaviour
{
  [Networked, Capacity(14)]
  string MyString { get; set; }

  [Networked, Capacity(8)]
  NetworkArray<byte> MyArray { get; }
}

トップに戻る

OnChangedに反応する

Fusion では、Networked プロパティが変更されたときに、ゲームコードをトリガーすることができます。リアクティブなコードを書くには、[Networked] 属性にある (OnChanged) パラメータを使用します。

public class Powerup : NetworkBehaviour
{
    [Networked(OnChanged = nameof(OnTypeChanged))] public Type type { get; set; }

    // Has to be public static void
    public static void OnTypeChanged(Changed<Powerup> changed)
    {
        changed.Behaviour.OnTypeChanged();
    }

    private void OnTypeChanged()
    {
        // Some logic reacting to the value change of the "type" property
    }
}

コールバック名の指定に加えて、どのマシンでコールバックが実行されるかを制御することが可能です。

  • OnChangedLocal (default false): trueに設定すると、プロパティを変更したマシン上 でも イベントフックが呼び出されるようになります。
  • OnChangedRemote (default true): プロパティを変更したマシン上でしかイベントフックを呼ばれないようにするには、falseに設定します。

トップに戻る

オーバーライド可能なメソッド

NetworkObjectには、いくつかのライフサイクルメソッドが追加されており、これらはすべて、SimulationBehaviourNetworkBehaviourを実装する際にオーバーライドすることができます。

関数 説明
FixedUpdateNetwork() Fusionの固定タイムステップのコールバックです。ゲームのコアロジックに使用します。
Spawned() ポストスポーンのコールバック
Despawned(bool hasState) ネットワークオブジェクトがデスポーンされる前に呼び出されます。
---
bool hasState: 動作の状態にまだアクセスできるかどうか。
Render() シミュレーション後のフレームレンダリングコールバック。すべてのシミュレーションが終了した後に実行されます。Fusionが物理演算を行う場合、UnityのUpdateの代わりに使用します。

トップに戻る

FixedUpdateNetwork

FixedUpdateNetwork()(FUN()と略されます)は、あるティックから次のティックへと新しい状態をシミュレートするときに呼び出されます。この間隔のタイムステップは、NetworkProjectConfigアセットのSimulation > Tick Rateで定義されます。このタイムステップは、任意の SimulationBehaviourNetworkBehaviour から、Runner.DeltaTime プロパティを使ってアクセスできます。

FixedUpdateNetwork()は、同じ状態遷移に対して複数回呼び出すことができ、サーバーから受信した更新情報(ground truth)に基づいて、現在の予測状態を再シミュレーションします。 [Networked] のプロパティでは、再シミュレーションは透過的です。なぜなら、Fusionは再シミュレーションのためにFixedUpdateNetwork()を呼び出す前に、ネットワークの状態をリセットするからです。

重要: ネットワーク化されていない通常のローカルな状態変数(クラスメンバーなど)はリセットされず、単に状態の進行が追加されたとみなされます。

ドキュメントのトップへ戻る