Skip to content

Commit a115c83

Browse files
fix: NetworkAnimator parameter writebuffer limits causes exception (#3108)
* fix Pre-calculate the required parameter write size needed as opposed to using the legacy constant value. * fix Decided this all could be handled during the Awake method with no need to pre-calculate during validation. Also made adjustments to have a more precise calculation for the size needed. * update Adding change log entry
1 parent a0f1165 commit a115c83

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

com.unity.netcode.gameobjects/CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ Additional documentation and release notes are available at [Multiplayer Documen
1212

1313
### Fixed
1414

15+
- Fixed issue where `NetworkAnimator` would statically allocate write buffer space for `Animator` parameters that could cause a write error if the number of parameters exceeded the space allocated.
16+
1517
### Changed
1618

1719
## [2.1.1] - 2024-10-18

com.unity.netcode.gameobjects/Runtime/Components/NetworkAnimator.cs

+44-6
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ private void BuildDestinationToTransitionInfoTable()
230230
}
231231
}
232232

233+
233234
#if UNITY_EDITOR
234235
private void ParseStateMachineStates(int layerIndex, ref AnimatorController animatorController, ref AnimatorStateMachine stateMachine)
235236
{
@@ -263,7 +264,6 @@ private void ParseStateMachineStates(int layerIndex, ref AnimatorController anim
263264
{
264265
case AnimatorControllerParameterType.Trigger:
265266
{
266-
267267
if (transition.destinationStateMachine != null)
268268
{
269269
var destinationStateMachine = transition.destinationStateMachine;
@@ -297,6 +297,7 @@ private void ParseStateMachineStates(int layerIndex, ref AnimatorController anim
297297
}
298298
}
299299
}
300+
300301
#endif
301302

302303
/// <summary>
@@ -507,10 +508,6 @@ protected virtual bool OnIsServerAuthoritative()
507508
return NetworkManager ? !NetworkManager.DistributedAuthorityMode : true;
508509
}
509510

510-
// Animators only support up to 32 parameters
511-
// TODO: Look into making this a range limited property
512-
private const int k_MaxAnimationParams = 32;
513-
514511
private int[] m_TransitionHash;
515512
private int[] m_AnimationHash;
516513
private float[] m_LayerWeights;
@@ -534,7 +531,7 @@ private unsafe struct AnimatorParamCache
534531
}
535532

536533
// 128 bytes per Animator
537-
private FastBufferWriter m_ParameterWriter = new FastBufferWriter(k_MaxAnimationParams * sizeof(float), Allocator.Persistent);
534+
private FastBufferWriter m_ParameterWriter;
538535

539536
private NativeArray<AnimatorParamCache> m_CachedAnimatorParameters;
540537

@@ -586,6 +583,14 @@ public override void OnDestroy()
586583

587584
protected virtual void Awake()
588585
{
586+
if (!m_Animator)
587+
{
588+
#if !UNITY_EDITOR
589+
Debug.LogError($"{nameof(NetworkAnimator)} {name} does not have an {nameof(UnityEngine.Animator)} assigned to it. The {nameof(NetworkAnimator)} will not initialize properly.");
590+
#endif
591+
return;
592+
}
593+
589594
int layers = m_Animator.layerCount;
590595
// Initializing the below arrays for everyone handles an issue
591596
// when running in owner authoritative mode and the owner changes.
@@ -615,6 +620,9 @@ protected virtual void Awake()
615620
}
616621
}
617622

623+
// The total initialization size calculated for the m_ParameterWriter write buffer.
624+
var totalParameterSize = sizeof(uint);
625+
618626
// Build our reference parameter values to detect when they change
619627
var parameters = m_Animator.parameters;
620628
m_CachedAnimatorParameters = new NativeArray<AnimatorParamCache>(parameters.Length, Allocator.Persistent);
@@ -655,7 +663,37 @@ protected virtual void Awake()
655663
}
656664

657665
m_CachedAnimatorParameters[i] = cacheParam;
666+
667+
// Calculate parameter sizes (index + type size)
668+
switch (parameter.type)
669+
{
670+
case AnimatorControllerParameterType.Int:
671+
{
672+
totalParameterSize += sizeof(int) * 2;
673+
break;
674+
}
675+
case AnimatorControllerParameterType.Bool:
676+
case AnimatorControllerParameterType.Trigger:
677+
{
678+
// Bool is serialized to 1 byte
679+
totalParameterSize += sizeof(int) + 1;
680+
break;
681+
}
682+
case AnimatorControllerParameterType.Float:
683+
{
684+
totalParameterSize += sizeof(int) + sizeof(float);
685+
break;
686+
}
687+
}
658688
}
689+
690+
if (m_ParameterWriter.IsInitialized)
691+
{
692+
m_ParameterWriter.Dispose();
693+
}
694+
695+
// Create our parameter write buffer for serialization
696+
m_ParameterWriter = new FastBufferWriter(totalParameterSize, Allocator.Persistent);
659697
}
660698

661699
/// <summary>

0 commit comments

Comments
 (0)