Fusionのオブジェクト型の同期
概要
NetworkObject
やNetworkBehaviour
の参照は、ネットワークプロパティにすることができます。(備考:INetworkStruct
内では無効です)
ネットワークプロパティのNetworkObject
/NetworkBehaviour
の参照は、内部的にNetworkId
/NetworkBehaviourId
に変換されます。
ILWeaverが生成するSet
メソッドは、オブジェクトの参照をIDに変換(ラップ)し、IDを値として同期します。
ILWeaverが生成するGet
メソッドは、Runner.TryGetObject()
やRunner.TryGetBehaviour()
メソッドを使用して、IDをオブジェクトの参照に変換(アンラップ)します。
C#
[Networked] public NetworkObject MyNetworkObject { get; set; }
[Networked] public CustomNetworkBehaviour MyNetworkBehaviour { get; set; }
この自動化は便利ではありますが、
- 明示的なnull値
- アンラップの失敗
は、どちらもGet
メソッドでnullが返るため、2つを区別する方法がありません。
代替案として、NetworkObject
/NetworkBehaviour
の参照を使用するかわりに、NetworkId
/NetworkBehaviourId
の値を直接使用します。
オブジェクトをIDによって明示的に同期すると、null値を検知することができます。
- 0なら、明示的なnullを指す
- 0より大きい値なら、オブジェクトを指すが、そのオブジェクトは現在ローカルに存在しない(アンラップの失敗)
NetworkIdの使用例
C#
using Fusion;
public class SyncNetworkObjectExample : NetworkBehaviour
{
// NetworkId is backed by one int value.
// A zero value (default) represents null.
[Networked] public NetworkId SyncedNetworkObjectId { get; set; }
private void SetObject(NetworkObject netObj)
{
SyncedNetworkObjectId = netObj != null ? netObj.Id : default;
}
bool TryResolve(out NetworkObject no)
{
// A default (0) value indicates an explicit null value.
// Return true to represent successfully resolving this to null.
if (SyncedNetworkObjectId == default)
{
no = null;
return true;
}
// Find the object using the non-null id value.
// Return true if the lookup was successful.
// Return false and null if the NetworkObject could not be found on the local Runner.
bool found = Runner.TryFindObject(SyncedNetworkObjectId, out var obj);
no = obj;
return found;
}
}
NetworkBehaviourIdの使用例
C#
using Fusion;
public class SyncNetworkBehaviourExample : NetworkBehaviour
{
// NetworkId is backed by two int values.
// Object = NetworkObject.Id (value of 0 represents null/Invalid).
// Behaviour = NetworkBehaviour index in GameObject hierarchy.
[Networked] public NetworkBehaviourId SyncedNetworkBehaviourId { get; set; }
private void SetBehaviour(NetworkBehaviour nb)
{
SyncedNetworkBehaviourId = nb != null ? nb.Id : default;
}
bool TryResolve(out NetworkBehaviour no)
{
// A default (0) value indicates an explicit null value.
// Return true to represent successfully resolving this to null.
if (SyncedNetworkBehaviourId == default)
{
no = null;
return true;
}
// Find the NetworkBehaviour using the non-default id value.
// Return true if the lookup was successful.
// Return false and null if the NetworkObject could not be found on the local Runner.
bool found = Runner.TryFindBehaviour(SyncedNetworkBehaviourId, out var obj);
no = obj;
return found;
}
}
Back to top