using Unity.Collections; using Unity.Netcode; using UnityEngine; public sealed class PlayerIdentity : NetworkBehaviour, IPlayerSystem { private readonly NetworkVariable displayName = new( new FixedString64Bytes("Worker"), NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Owner); private TextMesh nameLabel; private bool isInitialized; public string DisplayName => displayName.Value.ToString(); public void Initialize(PlayerFacade facade) { isInitialized = true; } public override void OnNetworkSpawn() { displayName.OnValueChanged += HandleNameChanged; CreateNameLabel(); HandleNameChanged(default, displayName.Value); if (IsOwner) { string localName = NetworkSessionController.Instance != null ? NetworkSessionController.Instance.LocalPlayerName : "Worker"; displayName.Value = new FixedString64Bytes(localName); } } public override void OnNetworkDespawn() { displayName.OnValueChanged -= HandleNameChanged; } private void LateUpdate() { if (!isInitialized || nameLabel == null || Camera.main == null) return; Vector3 cameraPosition = Camera.main.transform.position; nameLabel.transform.rotation = Quaternion.LookRotation(nameLabel.transform.position - cameraPosition); } private void CreateNameLabel() { if (nameLabel != null) return; var labelObject = new GameObject("PlayerNameLabel"); labelObject.transform.SetParent(transform, false); labelObject.transform.localPosition = new Vector3(0f, 2.25f, 0f); labelObject.transform.localScale = Vector3.one * 0.12f; nameLabel = labelObject.AddComponent(); nameLabel.anchor = TextAnchor.MiddleCenter; nameLabel.alignment = TextAlignment.Center; nameLabel.fontSize = 48; nameLabel.characterSize = 0.1f; nameLabel.color = Color.white; } private void HandleNameChanged(FixedString64Bytes previousValue, FixedString64Bytes newValue) { if (nameLabel != null) nameLabel.text = newValue.ToString(); } }