// helper function for [SyncVar] NetworkIdentities. // dirtyBit is a mask like 00010 protected void SetSyncVarNetworkBehaviour <T>(T newBehaviour, ref T behaviourField, ulong dirtyBit, ref NetworkBehaviourSyncVar syncField) where T : NetworkBehaviour { if (GetSyncVarHookGuard(dirtyBit)) { return; } uint newNetId = 0; int componentIndex = 0; if (newBehaviour != null) { newNetId = newBehaviour.netId; componentIndex = newBehaviour.ComponentIndex; if (newNetId == 0) { Debug.LogWarning($"{nameof(SetSyncVarNetworkBehaviour)} NetworkIdentity {newBehaviour} has a zero netId. Maybe it is not spawned yet?"); } } syncField = new NetworkBehaviourSyncVar(newNetId, componentIndex); SetSyncVarDirtyBit(dirtyBit); // assign new one on the server, and in case we ever need it on client too behaviourField = newBehaviour; // Debug.Log($"SetSyncVarNetworkBehaviour NetworkIdentity {GetType().Name} bit [{dirtyBit}] netIdField:{oldField}->{syncField}"); }
public void GeneratedSyncVarDeserialize_NetworkBehaviour <T>(ref T field, Action <T, T> OnChanged, NetworkReader reader, ref NetworkBehaviourSyncVar netIdField) where T : NetworkBehaviour { NetworkBehaviourSyncVar previousNetId = netIdField; T previousBehaviour = field; netIdField = reader.ReadNetworkBehaviourSyncVar(); // get the new NetworkBehaviour now that netId field is set field = GetSyncVarNetworkBehaviour(netIdField, ref field); // any hook? then call if changed. if (OnChanged != null && !SyncVarEqual(previousNetId, ref netIdField)) { OnChanged(previousBehaviour, field); } }
protected bool SyncVarNetworkBehaviourEqual<T>(T newBehaviour, NetworkBehaviourSyncVar syncField) where T : NetworkBehaviour { uint newNetId = 0; int newComponentIndex = 0; if (newBehaviour != null) { newNetId = newBehaviour.netId; newComponentIndex = newBehaviour.ComponentIndex; if (newNetId == 0) { logger.LogWarning("SetSyncVarNetworkIdentity NetworkIdentity " + newBehaviour + " has a zero netId. Maybe it is not spawned yet?"); } } // netId changed? return syncField.Equals(newNetId, newComponentIndex); }
// helper function for [SyncVar] NetworkIdentities. // -> ref GameObject as second argument makes OnDeserialize processing easier protected T GetSyncVarNetworkBehaviour <T>(NetworkBehaviourSyncVar syncNetBehaviour, ref T behaviourField) where T : NetworkBehaviour { // server always uses the field if (isServer) { return(behaviourField); } // client always looks up based on netId because objects might get in and out of range // over and over again, which shouldn't null them forever if (!NetworkClient.spawned.TryGetValue(syncNetBehaviour.netId, out NetworkIdentity identity)) { return(null); } behaviourField = identity.NetworkBehaviours[syncNetBehaviour.componentIndex] as T; return(behaviourField); }
public void GeneratedSyncVarSetter_NetworkBehaviour <T>(T value, ref T field, ulong dirtyBit, Action <T, T> OnChanged, ref NetworkBehaviourSyncVar netIdField) where T : NetworkBehaviour { if (!SyncVarNetworkBehaviourEqual(value, netIdField)) { T oldValue = field; SetSyncVarNetworkBehaviour(value, ref field, dirtyBit, ref netIdField); // call hook (if any) if (OnChanged != null) { // in host mode, setting a SyncVar calls the hook directly. // in client-only mode, OnDeserialize would call it. // we use hook guard to protect against deadlock where hook // changes syncvar, calling hook again. if (NetworkServer.localClientActive && !GetSyncVarHookGuard(dirtyBit)) { SetSyncVarHookGuard(dirtyBit, true); OnChanged(oldValue, value); SetSyncVarHookGuard(dirtyBit, false); } } } }