Skip to content

Commit 8cb5a6d

Browse files
small CPU performance improvements (#590)
1 parent f64695e commit 8cb5a6d

File tree

5 files changed

+66
-21
lines changed

5 files changed

+66
-21
lines changed

Assets/BossRoom/Scripts/Client/AnimationCallbacks/AnimatorFootstepSounds.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using UnityEngine;
3+
using UnityEngine.Assertions;
34

45
namespace Unity.Multiplayer.Samples.BossRoom.Visual
56
{
@@ -63,6 +64,8 @@ public class AnimatorFootstepSounds : MonoBehaviour
6364
[Tooltip("If the speed variable is between WalkSpeedThreshold and this, we're running. (Higher than this means no sound)")]
6465
private float m_RunSpeedThreshold = 1.2f;
6566

67+
float m_LastSpeed;
68+
6669
void Awake()
6770
{
6871
if (!m_Animator)
@@ -73,17 +76,24 @@ void Awake()
7376

7477
private void Update()
7578
{
76-
if (!m_Animator || !m_AudioSource || !m_WalkFootstepAudioClip || !m_RunFootstepAudioClip || m_AnimatorVariableHash == 0)
79+
if (!m_Animator)
7780
{
7881
// we can't actually run since we don't have the stuff we need. So just stop updating
7982
enabled = false;
8083
return;
8184
}
8285

86+
var speed = m_Animator.GetFloat(m_AnimatorVariableHash);
87+
88+
if (Mathf.Approximately(speed, m_LastSpeed))
89+
{
90+
return;
91+
}
92+
8393
// choose which sound effect to use based on how fast we're walking
8494
AudioClip clipToUse = null;
8595
float volume = 0;
86-
float speed = m_Animator.GetFloat(m_AnimatorVariableHash);
96+
8797
if (speed <= m_TooSlowThreshold)
8898
{
8999
// we could have a "VERY slow walk" sound... but we don't, so just play nothing
@@ -117,6 +127,8 @@ private void Update()
117127
m_AudioSource.loop = true;
118128
m_AudioSource.Play();
119129
}
130+
131+
m_LastSpeed = speed;
120132
}
121133

122134
#if UNITY_EDITOR
@@ -128,9 +140,17 @@ private void Update()
128140
private void OnValidate()
129141
{
130142
m_AnimatorVariableHash = Animator.StringToHash(m_AnimatorVariable);
143+
Assert.IsTrue(m_AnimatorVariableHash != 0);
131144

132145
if (m_AudioSource == null)
146+
{
133147
m_AudioSource = GetComponent<AudioSource>();
148+
}
149+
Assert.IsNotNull(m_AudioSource);
150+
151+
Assert.IsNotNull(m_WalkFootstepAudioClip);
152+
153+
Assert.IsNotNull(m_RunFootstepAudioClip);
134154
}
135155
#endif
136156
}

Assets/BossRoom/Scripts/Client/Game/Character/ClientCharacterVisualization.cs

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using Unity.Netcode;
33
using UnityEngine;
4-
using UnityEngine.Assertions;
54
using Unity.Multiplayer.Samples.BossRoom.Client;
65

76
namespace Unity.Multiplayer.Samples.BossRoom.Visual
@@ -60,6 +59,10 @@ public class ClientCharacterVisualization : NetworkBehaviour
6059

6160
Quaternion m_LerpedRotation;
6261

62+
bool m_IsHost;
63+
64+
float m_CurrentSpeed;
65+
6366
void Awake()
6467
{
6568
enabled = false;
@@ -74,6 +77,8 @@ public override void OnNetworkSpawn()
7477

7578
enabled = true;
7679

80+
m_IsHost = IsHost;
81+
7782
m_ActionViz = new ActionVisualization(this);
7883

7984
m_NetState = GetComponentInParent<NetworkCharacterState>();
@@ -85,6 +90,8 @@ public override void OnNetworkSpawn()
8590
m_NetState.CancelActionsByTypeEventClient += CancelActionFXByType;
8691
m_NetState.OnStopChargingUpClient += OnStoppedChargingUp;
8792
m_NetState.IsStealthy.OnValueChanged += OnStealthyChanged;
93+
m_NetState.MovementStatus.OnValueChanged += OnMovementStatusChanged;
94+
OnMovementStatusChanged(MovementStatus.Normal,m_NetState.MovementStatus.Value);
8895

8996
// sync our visualization position & rotation to the most up to date version received from server
9097
transform.SetPositionAndRotation(m_PhysicsWrapper.Transform.position, m_PhysicsWrapper.Transform.rotation);
@@ -210,15 +217,14 @@ void SetAppearanceSwap()
210217
/// <summary>
211218
/// Returns the value we should set the Animator's "Speed" variable, given current gameplay conditions.
212219
/// </summary>
213-
float GetVisualMovementSpeed()
220+
float GetVisualMovementSpeed(MovementStatus movementStatus)
214221
{
215-
Assert.IsNotNull(m_VisualizationConfiguration);
216222
if (m_NetState.NetworkLifeState.LifeState.Value != LifeState.Alive)
217223
{
218224
return m_VisualizationConfiguration.SpeedDead;
219225
}
220226

221-
switch (m_NetState.MovementStatus.Value)
227+
switch (movementStatus)
222228
{
223229
case MovementStatus.Idle:
224230
return m_VisualizationConfiguration.SpeedIdle;
@@ -233,17 +239,22 @@ float GetVisualMovementSpeed()
233239
case MovementStatus.Walking:
234240
return m_VisualizationConfiguration.SpeedWalking;
235241
default:
236-
throw new Exception($"Unknown MovementStatus {m_NetState.MovementStatus.Value}");
242+
throw new Exception($"Unknown MovementStatus {movementStatus}");
237243
}
238244
}
239245

246+
void OnMovementStatusChanged(MovementStatus previousValue, MovementStatus newValue)
247+
{
248+
m_CurrentSpeed = GetVisualMovementSpeed(newValue);
249+
}
250+
240251
void Update()
241252
{
242253
// On the host, Characters are translated via ServerCharacterMovement's FixedUpdate method. To ensure that
243254
// the game camera tracks a GameObject moving in the Update loop and therefore eliminate any camera jitter,
244255
// this graphics GameObject's position is smoothed over time on the host. Clients do not need to perform any
245256
// positional smoothing since NetworkTransform will interpolate position updates on the root GameObject.
246-
if (IsHost)
257+
if (m_IsHost)
247258
{
248259
// Note: a cached position (m_LerpedPosition) and rotation (m_LerpedRotation) are created and used as
249260
// the starting point for each interpolation since the root's position and rotation are modified in
@@ -258,7 +269,7 @@ void Update()
258269
if (m_ClientVisualsAnimator)
259270
{
260271
// set Animator variables here
261-
OurAnimator.SetFloat(m_VisualizationConfiguration.SpeedVariableID, GetVisualMovementSpeed());
272+
OurAnimator.SetFloat(m_VisualizationConfiguration.SpeedVariableID, m_CurrentSpeed);
262273
}
263274

264275
m_ActionViz.Update();

Assets/BossRoom/Scripts/Server/Game/Character/ServerCharacterMovement.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class ServerCharacterMovement : NetworkBehaviour
3434

3535
private MovementState m_MovementState;
3636

37+
MovementStatus m_PreviousState;
38+
3739
[SerializeField]
3840
private ServerCharacter m_CharLogic;
3941

@@ -169,7 +171,12 @@ private void FixedUpdate()
169171
{
170172
PerformMovement();
171173

172-
m_NetworkCharacterState.MovementStatus.Value = GetMovementStatus();
174+
var currentState = GetMovementStatus(m_MovementState);
175+
if (m_PreviousState != currentState)
176+
{
177+
m_NetworkCharacterState.MovementStatus.Value = currentState;
178+
m_PreviousState = currentState;
179+
}
173180
}
174181

175182
public override void OnNetworkDespawn()
@@ -259,9 +266,9 @@ private float GetBaseMovementSpeed()
259266
/// Determines the appropriate MovementStatus for the character. The
260267
/// MovementStatus is used by the client code when animating the character.
261268
/// </summary>
262-
private MovementStatus GetMovementStatus()
269+
private MovementStatus GetMovementStatus(MovementState movementState)
263270
{
264-
switch (m_MovementState)
271+
switch (movementState)
265272
{
266273
case MovementState.Idle:
267274
return MovementStatus.Idle;

Assets/BossRoom/Scripts/Shared/Game/Action/ActionBase.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using UnityEngine;
23

34
namespace Unity.Multiplayer.Samples.BossRoom
@@ -31,8 +32,10 @@ public ActionDescription Description
3132
{
3233
get
3334
{
34-
var found = GameDataSource.Instance.ActionDataByType.TryGetValue(Data.ActionTypeEnum, out var result);
35-
Debug.AssertFormat(found, "Tried to find ActionType %s but it was missing from GameDataSource!", Data.ActionTypeEnum);
35+
if (!GameDataSource.Instance.ActionDataByType.TryGetValue(Data.ActionTypeEnum, out var result))
36+
{
37+
throw new KeyNotFoundException($"Tried to find ActionType {Data.ActionTypeEnum} but it was missing from GameDataSource!");
38+
}
3639

3740
return result;
3841
}

Assets/BossRoom/Scripts/Shared/Net/NetworkStats.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,14 @@ public ExponentialMovingAverageCalculator(float average)
5656

5757
ClientRpcParams m_PongClientParams;
5858

59+
bool m_IsServer;
60+
61+
string m_TextToDisplay;
62+
5963
public override void OnNetworkSpawn()
6064
{
65+
m_IsServer = IsServer;
66+
6167
bool isClientOnly = IsClient && !IsServer;
6268
if (!IsOwner && isClientOnly) // we don't want to track player ghost stats, only our own
6369
{
@@ -101,8 +107,7 @@ void InitializeTextLine(string defaultText, out TextMeshProUGUI textComponent)
101107

102108
void FixedUpdate()
103109
{
104-
var textToDisplay = string.Empty;
105-
if (!IsServer)
110+
if (!m_IsServer)
106111
{
107112
if (Time.realtimeSinceStartup - m_LastPingTime > k_PingIntervalSeconds)
108113
{
@@ -118,18 +123,17 @@ void FixedUpdate()
118123

119124
if (m_TextStat != null)
120125
{
121-
textToDisplay = $"{textToDisplay}RTT: {(m_BossRoomRTT.Average * 1000).ToString("0")} ms;\nUTP RTT {m_UtpRTT.Average.ToString("0")} ms";
126+
m_TextToDisplay = $"RTT: {(m_BossRoomRTT.Average * 1000).ToString("0")} ms;\nUTP RTT {m_UtpRTT.Average.ToString("0")} ms";
122127
}
123128
}
124-
125-
if (IsServer)
129+
else
126130
{
127-
textToDisplay = $"{textToDisplay}Connected players: {NetworkManager.Singleton.ConnectedClients.Count.ToString()} ";
131+
m_TextToDisplay = $"Connected players: {NetworkManager.Singleton.ConnectedClients.Count.ToString()}";
128132
}
129133

130134
if (m_TextStat)
131135
{
132-
m_TextStat.text = textToDisplay;
136+
m_TextStat.text = m_TextToDisplay;
133137
}
134138
}
135139

0 commit comments

Comments
 (0)