From 0ab92933de4dff1130cdfbd8e21b790009c2a10a Mon Sep 17 00:00:00 2001 From: MelekTaus Moribundus Date: Wed, 8 Jul 2026 20:40:56 +0200 Subject: [PATCH] Support styled multi-text nameplate label containers PlayerNameplates clones a GameObject container instead of a single TMP_Text and drives all TMP_Text children (text + distance font size), so the label template can be authored with layered texts (e.g. outline or shadow copies) in the editor. Co-Authored-By: Claude Fable 5 --- Assets/Scripts/Network/UI/PlayerNameplates.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/Assets/Scripts/Network/UI/PlayerNameplates.cs b/Assets/Scripts/Network/UI/PlayerNameplates.cs index 4334e4e..41cde0d 100644 --- a/Assets/Scripts/Network/UI/PlayerNameplates.cs +++ b/Assets/Scripts/Network/UI/PlayerNameplates.cs @@ -17,7 +17,7 @@ public class PlayerNameplates : MonoBehaviour { [Tooltip("Disabled label prototype under this canvas; cloned once per avatar. Author pivot (0.5, 0) + " + "bottom-center alignment so the text sits on top of the head anchor.")] - [SerializeField] private TMP_Text labelTemplate; + [SerializeField] private GameObject labelContainerTemplate; [Tooltip("Metres above the avatar's capsule top where the name anchors.")] [SerializeField] private float heightOffset = 0.1f; @@ -38,7 +38,8 @@ public class PlayerNameplates : MonoBehaviour private class Entry { public NetworkPlayerSetup setup; - public TMP_Text label; + public GameObject labelContainer; + public TMP_Text[] labels; public CharacterController capsule; // head-anchor height (present but disabled on remotes) public Renderer body; // own-avatar gate: first-person self-hides the mesh public string lastText; @@ -50,12 +51,12 @@ public class PlayerNameplates : MonoBehaviour private void Awake() { - if (labelTemplate) labelTemplate.gameObject.SetActive(false); + if (labelContainerTemplate) labelContainerTemplate.SetActive(false); } private void LateUpdate() { - if (!labelTemplate) return; + if (!labelContainerTemplate) return; if (_seenVersion != NetworkPlayerSetup.ActiveVersion) { @@ -73,7 +74,7 @@ public class PlayerNameplates : MonoBehaviour for (int i = 0; i < _entries.Count; i++) { Entry e = _entries[i]; - if (!e.setup || !e.label) continue; + if (!e.setup || !e.labelContainer || e.labels is null || e.labels.Length == 0) continue; bool show = cam; @@ -95,11 +96,11 @@ public class PlayerNameplates : MonoBehaviour else distance = Vector3.Distance(cam.transform.position, anchor); } - if (e.label.gameObject.activeSelf != show) - e.label.gameObject.SetActive(show); + if (e.labelContainer.activeSelf != show) + e.labelContainer.SetActive(show); if (!show) continue; - e.label.transform.position = new Vector3(screen.x, screen.y, 0f); + e.labelContainer.transform.position = new Vector3(screen.x, screen.y, 0f); float size = Mathf.Clamp(referenceFontSize * referenceDistance / Mathf.Max(distance, 0.01f), minFontSize, maxFontSize); @@ -107,13 +108,13 @@ public class PlayerNameplates : MonoBehaviour if (Mathf.Abs(size - e.lastSize) > 0.05f) { e.lastSize = size; - e.label.fontSize = size; + foreach (var label in e.labels) label.fontSize = size; } string text = e.setup.DisplayName; // same instance until renamed -> reference compare suffices if (!ReferenceEquals(text, e.lastText)) { e.lastText = text; - e.label.text = text; + foreach (var label in e.labels) label.text = text; } } } @@ -130,7 +131,7 @@ public class PlayerNameplates : MonoBehaviour private void Rebuild() { for (int i = 0; i < _entries.Count; i++) - if (_entries[i].label) Destroy(_entries[i].label.gameObject); + if (_entries[i].labelContainer) Destroy(_entries[i].labelContainer); _entries.Clear(); var avatars = NetworkPlayerSetup.Active; @@ -139,12 +140,12 @@ public class PlayerNameplates : MonoBehaviour var setup = avatars[i]; if (!setup) continue; - var label = Instantiate(labelTemplate, labelTemplate.transform.parent); - label.raycastTarget = false; + var labelContainer = Instantiate(labelContainerTemplate, labelContainerTemplate.transform.parent); _entries.Add(new Entry { setup = setup, - label = label, + labelContainer = labelContainer, + labels = labelContainer.GetComponentsInChildren(), capsule = setup.GetComponent(), body = setup.GetComponentInChildren(true), });