From abc9b7d5a7f5e5764e989b4a7803c9ad8618c2ba Mon Sep 17 00:00:00 2001 From: Fernando Cortez Date: Fri, 17 Jan 2025 14:52:57 -0500 Subject: [PATCH] fix: late joiners would be displayed as selected [MTTB-4] (#899) * first pass on fix * comment cleanup * changelog addition * reformatting --- Assets/Scripts/Gameplay/UI/PartyHUD.cs | 66 ++++++++++++++------------ CHANGELOG.md | 1 + 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/Assets/Scripts/Gameplay/UI/PartyHUD.cs b/Assets/Scripts/Gameplay/UI/PartyHUD.cs index f2c5b16b9..dfc346198 100644 --- a/Assets/Scripts/Gameplay/UI/PartyHUD.cs +++ b/Assets/Scripts/Gameplay/UI/PartyHUD.cs @@ -22,36 +22,33 @@ public class PartyHUD : MonoBehaviour ClientPlayerAvatarRuntimeCollection m_PlayerAvatars; [SerializeField] - private Image m_HeroPortrait; + Image m_HeroPortrait; [SerializeField] - private GameObject[] m_AllyPanel; + GameObject[] m_AllyPanel; [SerializeField] - private TextMeshProUGUI[] m_PartyNames; + TextMeshProUGUI[] m_PartyNames; [SerializeField] - private Image[] m_PartyClassSymbols; + Image[] m_PartyClassSymbols; [SerializeField] - private Slider[] m_PartyHealthSliders; + Slider[] m_PartyHealthSliders; [SerializeField] - private Image[] m_PartyHealthGodModeImages; + Image[] m_PartyHealthGodModeImages; // track a list of hero (slot 0) + allies - private ulong[] m_PartyIds; - - // track Hero's target to show when it is the Hero or an ally - private ulong m_CurrentTarget; + ulong[] m_PartyIds; ServerCharacter m_OwnedServerCharacter; ClientPlayerAvatar m_OwnedPlayerAvatar; - private Dictionary m_TrackedAllies = new Dictionary(); + Dictionary m_TrackedAllies = new Dictionary(); - private ClientInputSender m_ClientSender; + ClientInputSender m_ClientSender; void Awake() { @@ -150,6 +147,7 @@ void SetAllyData(ClientPlayerAvatar clientPlayerAvatar) ulong id = serverCharacter.NetworkObjectId; int slot = FindOrAddAlly(id); + // do nothing if not in a slot if (slot == -1) { @@ -189,19 +187,22 @@ void SetUIFromSlotData(int slot, ServerCharacter serverCharacter) #if UNITY_EDITOR || DEVELOPMENT_BUILD void SetAllyGodModeStatus(ulong id, bool newValue) { - int slot = FindOrAddAlly(id); + int slot = FindOrAddAlly(id, true); + // do nothing if not in a slot if (slot == -1) { return; } + m_PartyHealthGodModeImages[slot].gameObject.SetActive(newValue); } #endif void SetAllyHealth(ulong id, int hp) { - int slot = FindOrAddAlly(id); + int slot = FindOrAddAlly(id, true); + // do nothing if not in a slot if (slot == -1) { @@ -211,29 +212,20 @@ void SetAllyHealth(ulong id, int hp) m_PartyHealthSliders[slot].value = hp; } - private void OnHeroSelectionChanged(ulong prevTarget, ulong newTarget) + void OnHeroSelectionChanged(ulong prevTarget, ulong newTarget) { - SetHeroSelectFX(m_CurrentTarget, false); + SetHeroSelectFX(prevTarget, false); SetHeroSelectFX(newTarget, true); } // Helper to change name appearance for selected or unselected party members - // also updates m_CurrentTarget - private void SetHeroSelectFX(ulong target, bool selected) + void SetHeroSelectFX(ulong target, bool selected) { // check id against all party slots int slot = FindOrAddAlly(target, true); if (slot >= 0) { m_PartyNames[slot].color = selected ? Color.green : Color.white; - if (selected) - { - m_CurrentTarget = target; - } - else - { - m_CurrentTarget = 0; - } } } @@ -244,7 +236,7 @@ public void SelectPartyMember(int slot) } // helper to initialize the Allies array - safe to call multiple times - private void InitPartyArrays() + void InitPartyArrays() { if (m_PartyIds == null) { @@ -262,16 +254,26 @@ private void InitPartyArrays() // Helper to find ally slots, returns -1 if no slot is found for the id // If a slot is available one will be added for this id unless dontAdd=true - private int FindOrAddAlly(ulong id, bool dontAdd = false) + int FindOrAddAlly(ulong id, bool dontAdd = false) { // make sure allies array is ready InitPartyArrays(); + if (id == 0) + { + // special case: id of 0 is uninitialized party id + return -1; + } + int openslot = -1; for (int i = 0; i < m_PartyIds.Length; i++) { // if this ID is in the list, return the slot index - if (m_PartyIds[i] == id) { return i; } + if (m_PartyIds[i] == id) + { + return i; + } + // otherwise, record the first open slot (not slot 0 thats for the Hero) if (openslot == -1 && i > 0 && m_PartyIds[i] == 0) { @@ -287,6 +289,7 @@ private int FindOrAddAlly(ulong id, bool dontAdd = false) { // activeate the correct ally panel m_AllyPanel[openslot - 1].SetActive(true); + // and save ally ID to party array m_PartyIds[openslot] = id; return openslot; @@ -315,15 +318,18 @@ void RemoveHero() /// NetworkObjectID of the ally. void RemoveAlly(ulong id) { + // remove potential selected state of party member UI + SetHeroSelectFX(id, false); + for (int i = 0; i < m_PartyIds.Length; i++) { // if this ID is in the list, return the slot index if (m_PartyIds[i] == id) { m_AllyPanel[i - 1].SetActive(false); + // and save ally ID to party array m_PartyIds[i] = 0; - return; } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 61b885927..ab47a269e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ Additional documentation and release notes are available at [Multiplayer Documen * Changed the way characters are oriented when using skills. * Added the GetTotalDamage API to the IDamageable interface. This number is your maximum health minus your current health. * Changed the way MeleeAction selects a target when there are multiple targets to collide with. The target with the highest GetTotalDamage value (mentioned above) will be selected. +* Fixed a visual issue where a selected party member's party HUD slot would be displayed as selected (green) when the same or new party member joins the session in-game (#899) ## [2.5.0] - 2024-04-18