diff --git a/com.unity.netcode.gameobjects/CHANGELOG.md b/com.unity.netcode.gameobjects/CHANGELOG.md index a205a8a18d..89c4b4f86e 100644 --- a/com.unity.netcode.gameobjects/CHANGELOG.md +++ b/com.unity.netcode.gameobjects/CHANGELOG.md @@ -17,6 +17,7 @@ Additional documentation and release notes are available at [Multiplayer Documen ### Fixed +- 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. (#3124) - Fixed issue with the in-scene network prefab instance update menu tool where it was not properly updating scenes when invoked on the root prefab instance. (#3084) - Fixed issue where `NetworkAnimator` would send updates to non-observer clients. (#3058) - Fixed issue where an exception could occur when receiving a universal RPC for a `NetworkObject` that has been despawned. (#3055) diff --git a/com.unity.netcode.gameobjects/Components/NetworkAnimator.cs b/com.unity.netcode.gameobjects/Components/NetworkAnimator.cs index 2cae1d61a2..f588f818d7 100644 --- a/com.unity.netcode.gameobjects/Components/NetworkAnimator.cs +++ b/com.unity.netcode.gameobjects/Components/NetworkAnimator.cs @@ -481,10 +481,6 @@ protected virtual bool OnIsServerAuthoritative() return true; } - // Animators only support up to 32 parameters - // TODO: Look into making this a range limited property - private const int k_MaxAnimationParams = 32; - private int[] m_TransitionHash; private int[] m_AnimationHash; private float[] m_LayerWeights; @@ -508,7 +504,7 @@ private unsafe struct AnimatorParamCache } // 128 bytes per Animator - private FastBufferWriter m_ParameterWriter = new FastBufferWriter(k_MaxAnimationParams * sizeof(float), Allocator.Persistent); + private FastBufferWriter m_ParameterWriter; private NativeArray m_CachedAnimatorParameters; @@ -560,6 +556,14 @@ public override void OnDestroy() private void Awake() { + if (!m_Animator) + { +#if !UNITY_EDITOR + Debug.LogError($"{nameof(NetworkAnimator)} {name} does not have an {nameof(UnityEngine.Animator)} assigned to it. The {nameof(NetworkAnimator)} will not initialize properly."); +#endif + return; + } + int layers = m_Animator.layerCount; // Initializing the below arrays for everyone handles an issue // when running in owner authoritative mode and the owner changes. @@ -589,6 +593,9 @@ private void Awake() } } + // The total initialization size calculated for the m_ParameterWriter write buffer. + var totalParameterSize = sizeof(uint); + // Build our reference parameter values to detect when they change var parameters = m_Animator.parameters; m_CachedAnimatorParameters = new NativeArray(parameters.Length, Allocator.Persistent); @@ -629,7 +636,37 @@ private void Awake() } m_CachedAnimatorParameters[i] = cacheParam; + + // Calculate parameter sizes (index + type size) + switch (parameter.type) + { + case AnimatorControllerParameterType.Int: + { + totalParameterSize += sizeof(int) * 2; + break; + } + case AnimatorControllerParameterType.Bool: + case AnimatorControllerParameterType.Trigger: + { + // Bool is serialized to 1 byte + totalParameterSize += sizeof(int) + 1; + break; + } + case AnimatorControllerParameterType.Float: + { + totalParameterSize += sizeof(int) + sizeof(float); + break; + } + } } + + if (m_ParameterWriter.IsInitialized) + { + m_ParameterWriter.Dispose(); + } + + // Create our parameter write buffer for serialization + m_ParameterWriter = new FastBufferWriter(totalParameterSize, Allocator.Persistent); } ///