@@ -116,10 +116,26 @@ public enum AttachState
116116 /// </summary>
117117 protected AttachableNode m_AttachableNode { get ; private set ; }
118118
119- private NetworkVariable < NetworkBehaviourReference > m_AttachedNodeReference = new NetworkVariable < NetworkBehaviourReference > ( new NetworkBehaviourReference ( null ) ) ;
119+ private NetworkBehaviourReference m_AttachedNodeReference = new NetworkBehaviourReference ( null ) ;
120120 private Vector3 m_OriginalLocalPosition ;
121121 private Quaternion m_OriginalLocalRotation ;
122122
123+ /// <inheritdoc/>
124+ protected override void OnSynchronize < T > ( ref BufferSerializer < T > serializer )
125+ {
126+ // Example of how to synchronize late joining clients when using an RPC to update
127+ // a local property's state.
128+ if ( serializer . IsWriter )
129+ {
130+ serializer . SerializeValue ( ref m_AttachedNodeReference ) ;
131+ }
132+ else
133+ {
134+ serializer . SerializeValue ( ref m_AttachedNodeReference ) ;
135+ }
136+ base . OnSynchronize ( ref serializer ) ;
137+ }
138+
123139 /// <summary>
124140 /// If you create a custom <see cref="AttachableBehaviour"/> and override this method, you must invoke
125141 /// this base instance of <see cref="Awake"/>.
@@ -133,21 +149,6 @@ protected virtual void Awake()
133149 m_AttachableNode = null ;
134150 }
135151
136- /// <inheritdoc/>
137- /// <remarks>
138- /// If you create a custom <see cref="AttachableBehaviour"/> and override this method, you must invoke
139- /// this base instance of <see cref="OnNetworkPostSpawn"/>.
140- /// </remarks>
141- protected override void OnNetworkPostSpawn ( )
142- {
143- if ( HasAuthority )
144- {
145- m_AttachedNodeReference . Value = new NetworkBehaviourReference ( null ) ;
146- }
147- m_AttachedNodeReference . OnValueChanged += OnAttachedNodeReferenceChanged ;
148- base . OnNetworkPostSpawn ( ) ;
149- }
150-
151152 /// <inheritdoc/>
152153 /// <remarks>
153154 /// If you create a custom <see cref="AttachableBehaviour"/> and override this method, you will want to
@@ -164,25 +165,20 @@ protected override void OnNetworkSessionSynchronized()
164165 /// <inheritdoc/>
165166 public override void OnNetworkDespawn ( )
166167 {
167- m_AttachedNodeReference . OnValueChanged -= OnAttachedNodeReferenceChanged ;
168168 InternalDetach ( ) ;
169169 if ( NetworkManager && ! NetworkManager . ShutdownInProgress )
170170 {
171171 // Notify of the changed attached state
172172 UpdateAttachState ( m_AttachState , m_AttachableNode ) ;
173173 }
174+ m_AttachedNodeReference = new NetworkBehaviourReference ( null ) ;
174175 base . OnNetworkDespawn ( ) ;
175176 }
176177
177- private void OnAttachedNodeReferenceChanged ( NetworkBehaviourReference previous , NetworkBehaviourReference current )
178- {
179- UpdateAttachedState ( ) ;
180- }
181-
182178 private void UpdateAttachedState ( )
183179 {
184180 var attachableNode = ( AttachableNode ) null ;
185- var shouldParent = m_AttachedNodeReference . Value . TryGet ( out attachableNode , NetworkManager ) ;
181+ var shouldParent = m_AttachedNodeReference . TryGet ( out attachableNode , NetworkManager ) ;
186182 var preState = shouldParent ? AttachState . Attaching : AttachState . Detaching ;
187183 var preNode = shouldParent ? attachableNode : m_AttachableNode ;
188184 shouldParent = shouldParent && attachableNode != null ;
@@ -310,8 +306,7 @@ public void Attach(AttachableNode attachableNode)
310306 return ;
311307 }
312308
313- // Update the attached node reference to the new attachable node.
314- m_AttachedNodeReference . Value = new NetworkBehaviourReference ( attachableNode ) ;
309+ ChangeReference ( new NetworkBehaviourReference ( attachableNode ) ) ;
315310 }
316311
317312 /// <summary>
@@ -344,7 +339,7 @@ public void Detach()
344339 return ;
345340 }
346341
347- if ( ! HasAuthority )
342+ if ( ! OnHasAuthority ( ) )
348343 {
349344 NetworkLog . LogError ( $ "[{ name } ][Detach][Not Authority] Client-{ NetworkManager . LocalClientId } is not the authority!") ;
350345 return ;
@@ -373,8 +368,40 @@ public void Detach()
373368 return ;
374369 }
375370
376- // Update the attached node reference to nothing-null.
377- m_AttachedNodeReference . Value = new NetworkBehaviourReference ( null ) ;
371+ ChangeReference ( new NetworkBehaviourReference ( null ) ) ;
372+ }
373+
374+ /// <summary>
375+ /// Override this method to change how the instance determines the authority.<br />
376+ /// The default is to use the <see cref="NetworkObject.HasAuthority"/> method.
377+ /// </summary>
378+ /// <remarks>
379+ /// Useful when using a <see cref="NetworkTopologyTypes.ClientServer"/> network topology and you would like
380+ /// to have the owner be the authority of this <see cref="ComponentController"/> instance.
381+ /// </remarks>
382+ /// <returns>true = has authoriy | false = does not have authority</returns>
383+ protected virtual bool OnHasAuthority ( )
384+ {
385+ return HasAuthority ;
386+ }
387+
388+ private void ChangeReference ( NetworkBehaviourReference networkBehaviourReference )
389+ {
390+ // Update the attached node reference to the new attachable node.
391+ m_AttachedNodeReference = networkBehaviourReference ;
392+ UpdateAttachedState ( ) ;
393+
394+ if ( OnHasAuthority ( ) )
395+ {
396+ // Send notification of the change in this property's state.
397+ UpdateAttachStateRpc ( m_AttachedNodeReference ) ;
398+ }
399+ }
400+
401+ [ Rpc ( SendTo . NotMe ) ]
402+ private void UpdateAttachStateRpc ( NetworkBehaviourReference attachedNodeReference )
403+ {
404+ ChangeReference ( attachedNodeReference ) ;
378405 }
379406 }
380407}
0 commit comments