Mirror Networking
SyncVarNetworkIdentity.cs
1// persistent NetworkIdentity SyncField which stores .netId internally.
2// this is necessary for cases like a player's target.
3// the target might run in and out of visibility range and become 'null'.
4// but the 'netId' remains and will always point to the monster if around.
5//
6// original Weaver code with netId workaround:
7/*
8 // USER:
9 [SyncVar(hook = "OnTargetChanged")]
10 public NetworkIdentity target;
11
12 // WEAVER GENERATED:
13 private uint ___targetNetId;
14
15 public NetworkIdentity Networktarget
16 {
17 get
18 {
19 return GetSyncVarNetworkIdentity(___targetNetId, ref target);
20 }
21 [param: In]
22 set
23 {
24 if (!SyncVarNetworkIdentityEqual(value, ___targetNetId))
25 {
26 NetworkIdentity networktarget = Networktarget;
27 SetSyncVarNetworkIdentity(value, ref target, 1uL, ref ___targetNetId);
28 if (NetworkServer.localClientActive && !GetSyncVarHookGuard(1uL))
29 {
30 SetSyncVarHookGuard(1uL, value: true);
31 OnTargetChanged(networktarget, value);
32 SetSyncVarHookGuard(1uL, value: false);
33 }
34 }
35 }
36 }
37*/
38using System;
39using System.Runtime.CompilerServices;
40
41namespace Mirror
42{
43 // SyncField<NetworkIdentity> only stores an uint netId.
44 // while providing .spawned lookup for convenience.
45 // NOTE: server always knows all spawned. consider caching the field again.
46 public class SyncVarNetworkIdentity : SyncVar<uint>
47 {
48 // .spawned lookup from netId overwrites base uint .Value
49 public new NetworkIdentity Value
50 {
51 [MethodImpl(MethodImplOptions.AggressiveInlining)]
52 get => Utils.GetSpawnedInServerOrClient(base.Value);
53 [MethodImpl(MethodImplOptions.AggressiveInlining)]
54 set => base.Value = value != null ? value.netId : 0;
55 }
56
57 // OnChanged Callback is for <uint, uint>.
58 // Let's also have one for <NetworkIdentity, NetworkIdentity>
59 public new event Action<NetworkIdentity, NetworkIdentity> Callback;
60
61 // overwrite CallCallback to use the NetworkIdentity version instead
62 [MethodImpl(MethodImplOptions.AggressiveInlining)]
63 protected override void InvokeCallback(uint oldValue, uint newValue) =>
64 Callback?.Invoke(Utils.GetSpawnedInServerOrClient(oldValue), Utils.GetSpawnedInServerOrClient(newValue));
65
66 // ctor
67 // 'value = null' so we can do:
68 // SyncVarNetworkIdentity = new SyncVarNetworkIdentity()
69 // instead of
70 // SyncVarNetworkIdentity = new SyncVarNetworkIdentity(null);
71 public SyncVarNetworkIdentity(NetworkIdentity value = null)
72 : base(value != null ? value.netId : 0) {}
73
74 // implicit conversion: NetworkIdentity value = SyncFieldNetworkIdentity
75 [MethodImpl(MethodImplOptions.AggressiveInlining)]
76 public static implicit operator NetworkIdentity(SyncVarNetworkIdentity field) => field.Value;
77
78 // implicit conversion: SyncFieldNetworkIdentity = value
79 // even if SyncField is readonly, it's still useful: SyncFieldNetworkIdentity = target;
80 [MethodImpl(MethodImplOptions.AggressiveInlining)]
81 public static implicit operator SyncVarNetworkIdentity(NetworkIdentity value) => new SyncVarNetworkIdentity(value);
82
83 // NOTE: overloading all == operators blocks '== null' checks with an
84 // "ambiguous invocation" error. that's good. this way user code like
85 // "player.target == null" won't compile instead of silently failing!
86
87 // == operator for comparisons like Player.target==monster
88 [MethodImpl(MethodImplOptions.AggressiveInlining)]
89 public static bool operator ==(SyncVarNetworkIdentity a, SyncVarNetworkIdentity b) =>
90 a.Value == b.Value;
91
92 [MethodImpl(MethodImplOptions.AggressiveInlining)]
93 public static bool operator !=(SyncVarNetworkIdentity a, SyncVarNetworkIdentity b) => !(a == b);
94
95 // == operator for comparisons like Player.target==monster
96 [MethodImpl(MethodImplOptions.AggressiveInlining)]
97 public static bool operator ==(SyncVarNetworkIdentity a, NetworkIdentity b) =>
98 a.Value == b;
99
100 [MethodImpl(MethodImplOptions.AggressiveInlining)]
101 public static bool operator !=(SyncVarNetworkIdentity a, NetworkIdentity b) => !(a == b);
102
103 // == operator for comparisons like Player.target==monster
104 [MethodImpl(MethodImplOptions.AggressiveInlining)]
105 public static bool operator ==(NetworkIdentity a, SyncVarNetworkIdentity b) =>
106 a == b.Value;
107
108 [MethodImpl(MethodImplOptions.AggressiveInlining)]
109 public static bool operator !=(NetworkIdentity a, SyncVarNetworkIdentity b) => !(a == b);
110
111 // if we overwrite == operators, we also need to overwrite .Equals.
112 [MethodImpl(MethodImplOptions.AggressiveInlining)]
113 public override bool Equals(object obj) => obj is SyncVarNetworkIdentity value && this == value;
114
115 [MethodImpl(MethodImplOptions.AggressiveInlining)]
116 public override int GetHashCode() => Value.GetHashCode();
117 }
118}
NetworkIdentity identifies objects across the network.