1
1
using Unity . Collections ;
2
2
using Unity . Collections . LowLevel . Unsafe ;
3
-
4
3
using UnityEngine ;
5
4
6
5
namespace Unity . Netcode . Components
@@ -14,14 +13,19 @@ public class NetworkAnimator : NetworkBehaviour
14
13
{
15
14
internal struct AnimationMessage : INetworkSerializable
16
15
{
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 ;
18
18
public float NormalizedTime ;
19
+ public int Layer ;
20
+ public float Weight ;
19
21
public byte [ ] Parameters ;
20
22
21
23
public void NetworkSerialize < T > ( BufferSerializer < T > serializer ) where T : IReaderWriter
22
24
{
23
25
serializer . SerializeValue ( ref StateHash ) ;
24
26
serializer . SerializeValue ( ref NormalizedTime ) ;
27
+ serializer . SerializeValue ( ref Layer ) ;
28
+ serializer . SerializeValue ( ref Weight ) ;
25
29
serializer . SerializeValue ( ref Parameters ) ;
26
30
}
27
31
}
@@ -54,10 +58,9 @@ public Animator Animator
54
58
// Animators only support up to 32 params
55
59
public static int K_MaxAnimationParams = 32 ;
56
60
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 ;
61
64
62
65
private unsafe struct AnimatorParamCache
63
66
{
@@ -100,12 +103,16 @@ public override void OnNetworkSpawn()
100
103
if ( IsServer )
101
104
{
102
105
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 ] ;
103
111
}
112
+
104
113
var parameters = m_Animator . parameters ;
105
114
m_CachedAnimatorParameters = new NativeArray < AnimatorParamCache > ( parameters . Length , Allocator . Persistent ) ;
106
115
107
- m_AnimationHash = - 1 ;
108
-
109
116
for ( var i = 0 ; i < parameters . Length ; i ++ )
110
117
{
111
118
var parameter = parameters [ i ] ;
@@ -157,66 +164,81 @@ public override void OnNetworkDespawn()
157
164
158
165
private void FixedUpdate ( )
159
166
{
160
- if ( ! m_SendMessagesAllowed )
167
+ if ( ! m_SendMessagesAllowed || ! m_Animator || ! m_Animator . enabled )
161
168
{
162
169
return ;
163
170
}
164
171
165
- int stateHash ;
166
- float normalizedTime ;
167
- if ( ! CheckAnimStateChanged ( out stateHash , out normalizedTime ) )
172
+ for ( int layer = 0 ; layer < m_Animator . layerCount ; layer ++ )
168
173
{
169
- return ;
170
- }
174
+ int stateHash ;
175
+ float normalizedTime ;
176
+ if ( ! CheckAnimStateChanged ( out stateHash , out normalizedTime , layer ) )
177
+ {
178
+ continue ;
179
+ }
171
180
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
+ } ;
177
188
178
- m_ParameterWriter . Seek ( 0 ) ;
179
- m_ParameterWriter . Truncate ( ) ;
189
+ m_ParameterWriter . Seek ( 0 ) ;
190
+ m_ParameterWriter . Truncate ( ) ;
180
191
181
- WriteParameters ( m_ParameterWriter ) ;
182
- animMsg . Parameters = m_ParameterWriter . ToArray ( ) ;
192
+ WriteParameters ( m_ParameterWriter ) ;
193
+ animMsg . Parameters = m_ParameterWriter . ToArray ( ) ;
183
194
184
- SendAnimStateClientRpc ( animMsg ) ;
195
+ SendAnimStateClientRpc ( animMsg ) ;
196
+ }
185
197
}
186
198
187
- private bool CheckAnimStateChanged ( out int stateHash , out float normalizedTime )
199
+ private bool CheckAnimStateChanged ( out int stateHash , out float normalizedTime , int layer )
188
200
{
201
+ bool shouldUpdate = false ;
189
202
stateHash = 0 ;
190
203
normalizedTime = 0 ;
191
204
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 ) )
193
213
{
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 ] )
196
216
{
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 ;
201
221
}
202
- return false ;
203
222
}
204
-
205
- AnimatorStateInfo st = m_Animator . GetCurrentAnimatorStateInfo ( 0 ) ;
206
- if ( st . fullPathHash != m_AnimationHash )
223
+ else
207
224
{
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 ] )
210
227
{
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 ;
214
238
}
215
- m_TransitionHash = 0 ;
216
- m_AnimationHash = st . fullPathHash ;
217
- return true ;
218
239
}
219
- return false ;
240
+
241
+ return shouldUpdate ;
220
242
}
221
243
222
244
/* $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
311
333
{
312
334
if ( animSnapshot . StateHash != 0 )
313
335
{
314
- m_AnimationHash = animSnapshot . StateHash ;
315
- m_Animator . Play ( animSnapshot . StateHash , 0 , animSnapshot . NormalizedTime ) ;
336
+ m_Animator . Play ( animSnapshot . StateHash , animSnapshot . Layer , animSnapshot . NormalizedTime ) ;
316
337
}
338
+ m_Animator . SetLayerWeight ( animSnapshot . Layer , animSnapshot . Weight ) ;
317
339
318
340
if ( animSnapshot . Parameters != null && animSnapshot . Parameters . Length != 0 )
319
341
{
0 commit comments