11using Unity . Collections ;
22using Unity . Collections . LowLevel . Unsafe ;
3-
43using UnityEngine ;
54
65namespace Unity . Netcode . Components
@@ -14,14 +13,19 @@ public class NetworkAnimator : NetworkBehaviour
1413 {
1514 internal struct AnimationMessage : INetworkSerializable
1615 {
17- public int StateHash ; // if non-zero, then Play() this animation, skipping transitions
16+ // state hash per layer. if non-zero, then Play() this animation, skipping transitions
17+ public int StateHash ;
1818 public float NormalizedTime ;
19+ public int Layer ;
20+ public float Weight ;
1921 public byte [ ] Parameters ;
2022
2123 public void NetworkSerialize < T > ( BufferSerializer < T > serializer ) where T : IReaderWriter
2224 {
2325 serializer . SerializeValue ( ref StateHash ) ;
2426 serializer . SerializeValue ( ref NormalizedTime ) ;
27+ serializer . SerializeValue ( ref Layer ) ;
28+ serializer . SerializeValue ( ref Weight ) ;
2529 serializer . SerializeValue ( ref Parameters ) ;
2630 }
2731 }
@@ -54,10 +58,9 @@ public Animator Animator
5458 // Animators only support up to 32 params
5559 public static int K_MaxAnimationParams = 32 ;
5660
57- private int m_TransitionHash ;
58-
59- private int m_AnimationHash ;
60- public int AnimationHash { get => m_AnimationHash ; }
61+ private int [ ] m_TransitionHash ;
62+ private int [ ] m_AnimationHash ;
63+ private float [ ] m_LayerWeights ;
6164
6265 private unsafe struct AnimatorParamCache
6366 {
@@ -100,12 +103,16 @@ public override void OnNetworkSpawn()
100103 if ( IsServer )
101104 {
102105 m_SendMessagesAllowed = true ;
106+ int layers = m_Animator . layerCount ;
107+
108+ m_TransitionHash = new int [ layers ] ;
109+ m_AnimationHash = new int [ layers ] ;
110+ m_LayerWeights = new float [ layers ] ;
103111 }
112+
104113 var parameters = m_Animator . parameters ;
105114 m_CachedAnimatorParameters = new NativeArray < AnimatorParamCache > ( parameters . Length , Allocator . Persistent ) ;
106115
107- m_AnimationHash = - 1 ;
108-
109116 for ( var i = 0 ; i < parameters . Length ; i ++ )
110117 {
111118 var parameter = parameters [ i ] ;
@@ -157,66 +164,81 @@ public override void OnNetworkDespawn()
157164
158165 private void FixedUpdate ( )
159166 {
160- if ( ! m_SendMessagesAllowed )
167+ if ( ! m_SendMessagesAllowed || ! m_Animator || ! m_Animator . enabled )
161168 {
162169 return ;
163170 }
164171
165- int stateHash ;
166- float normalizedTime ;
167- if ( ! CheckAnimStateChanged ( out stateHash , out normalizedTime ) )
172+ for ( int layer = 0 ; layer < m_Animator . layerCount ; layer ++ )
168173 {
169- return ;
170- }
174+ int stateHash ;
175+ float normalizedTime ;
176+ if ( ! CheckAnimStateChanged ( out stateHash , out normalizedTime , layer ) )
177+ {
178+ continue ;
179+ }
171180
172- var animMsg = new AnimationMessage
173- {
174- StateHash = stateHash ,
175- NormalizedTime = normalizedTime
176- } ;
181+ var animMsg = new AnimationMessage
182+ {
183+ StateHash = stateHash ,
184+ NormalizedTime = normalizedTime ,
185+ Layer = layer ,
186+ Weight = m_LayerWeights [ layer ]
187+ } ;
177188
178- m_ParameterWriter . Seek ( 0 ) ;
179- m_ParameterWriter . Truncate ( ) ;
189+ m_ParameterWriter . Seek ( 0 ) ;
190+ m_ParameterWriter . Truncate ( ) ;
180191
181- WriteParameters ( m_ParameterWriter ) ;
182- animMsg . Parameters = m_ParameterWriter . ToArray ( ) ;
192+ WriteParameters ( m_ParameterWriter ) ;
193+ animMsg . Parameters = m_ParameterWriter . ToArray ( ) ;
183194
184- SendAnimStateClientRpc ( animMsg ) ;
195+ SendAnimStateClientRpc ( animMsg ) ;
196+ }
185197 }
186198
187- private bool CheckAnimStateChanged ( out int stateHash , out float normalizedTime )
199+ private bool CheckAnimStateChanged ( out int stateHash , out float normalizedTime , int layer )
188200 {
201+ bool shouldUpdate = false ;
189202 stateHash = 0 ;
190203 normalizedTime = 0 ;
191204
192- if ( m_Animator . IsInTransition ( 0 ) )
205+ float layerWeightNow = m_Animator . GetLayerWeight ( layer ) ;
206+
207+ if ( ! Mathf . Approximately ( layerWeightNow , m_LayerWeights [ layer ] ) )
208+ {
209+ m_LayerWeights [ layer ] = layerWeightNow ;
210+ shouldUpdate = true ;
211+ }
212+ if ( m_Animator . IsInTransition ( layer ) )
193213 {
194- AnimatorTransitionInfo tt = m_Animator . GetAnimatorTransitionInfo ( 0 ) ;
195- if ( tt . fullPathHash != m_TransitionHash )
214+ AnimatorTransitionInfo tt = m_Animator . GetAnimatorTransitionInfo ( layer ) ;
215+ if ( tt . fullPathHash != m_TransitionHash [ layer ] )
196216 {
197- // first time in this transition
198- m_TransitionHash = tt . fullPathHash ;
199- m_AnimationHash = 0 ;
200- return true ;
217+ // first time in this transition for this layer
218+ m_TransitionHash [ layer ] = tt . fullPathHash ;
219+ m_AnimationHash [ layer ] = 0 ;
220+ shouldUpdate = true ;
201221 }
202- return false ;
203222 }
204-
205- AnimatorStateInfo st = m_Animator . GetCurrentAnimatorStateInfo ( 0 ) ;
206- if ( st . fullPathHash != m_AnimationHash )
223+ else
207224 {
208- // first time in this animation state
209- if ( m_AnimationHash != 0 )
225+ AnimatorStateInfo st = m_Animator . GetCurrentAnimatorStateInfo ( layer ) ;
226+ if ( st . fullPathHash != m_AnimationHash [ layer ] )
210227 {
211- // came from another animation directly - from Play()
212- stateHash = st . fullPathHash ;
213- normalizedTime = st . normalizedTime ;
228+ // first time in this animation state
229+ if ( m_AnimationHash [ layer ] != 0 )
230+ {
231+ // came from another animation directly - from Play()
232+ stateHash = st . fullPathHash ;
233+ normalizedTime = st . normalizedTime ;
234+ }
235+ m_TransitionHash [ layer ] = 0 ;
236+ m_AnimationHash [ layer ] = st . fullPathHash ;
237+ shouldUpdate = true ;
214238 }
215- m_TransitionHash = 0 ;
216- m_AnimationHash = st . fullPathHash ;
217- return true ;
218239 }
219- return false ;
240+
241+ return shouldUpdate ;
220242 }
221243
222244 /* $AS TODO: Right now we are not checking for changed values this is because
@@ -311,9 +333,9 @@ private unsafe void SendAnimStateClientRpc(AnimationMessage animSnapshot, Client
311333 {
312334 if ( animSnapshot . StateHash != 0 )
313335 {
314- m_AnimationHash = animSnapshot . StateHash ;
315- m_Animator . Play ( animSnapshot . StateHash , 0 , animSnapshot . NormalizedTime ) ;
336+ m_Animator . Play ( animSnapshot . StateHash , animSnapshot . Layer , animSnapshot . NormalizedTime ) ;
316337 }
338+ m_Animator . SetLayerWeight ( animSnapshot . Layer , animSnapshot . Weight ) ;
317339
318340 if ( animSnapshot . Parameters != null && animSnapshot . Parameters . Length != 0 )
319341 {
0 commit comments