using UnityEngine;
using UnityEngine.UI;
public class LabelItem : MonoBehaviour
{[Header("组件引用")]public Text textComponent;public RectTransform rectTransform;public CanvasGroup canvasGroup;[Header("目标对象")]public Transform targetTransform;public MeshRenderer targetRenderer;public LabelTarget labelTarget;private void Awake(){if (rectTransform == null)rectTransform = GetComponent<RectTransform>();if (textComponent == null)textComponent = GetComponentInChildren<Text>();if (canvasGroup == null)canvasGroup = GetComponent<CanvasGroup>();}public void Initialize(Transform target, MeshRenderer renderer = null, LabelTarget labelTarget = null, string labelText = ""){targetTransform = target;targetRenderer = renderer;this.labelTarget = labelTarget;string finalText = labelText;Color textColor = Color.white;if (labelTarget != null){finalText = labelTarget.GetLabelText();textColor = labelTarget.labelColor;}else if (target != null && string.IsNullOrEmpty(finalText)){finalText = target.name;}if (textComponent != null){textComponent.text = finalText;textComponent.color = textColor;}}public void UpdatePosition(Camera camera, Vector3 globalOffset, bool shouldShowByDistance = true){if (targetTransform == null || camera == null) return;Vector3 finalOffset = globalOffset;Vector2 screenOffset = Vector2.zero;if (labelTarget != null){finalOffset += labelTarget.GetWorldOffset();screenOffset = labelTarget.screenOffset;}Vector3 worldPosition = targetTransform.position + finalOffset;Vector3 screenPosition = camera.WorldToScreenPoint(worldPosition);if (screenPosition.z > 0 && screenPosition.z < camera.farClipPlane){screenPosition.x += screenOffset.x;screenPosition.y += screenOffset.y;Vector2 labelSize = rectTransform != null ? rectTransform.sizeDelta : Vector2.zero;float halfWidth = labelSize.x * 0.5f;float halfHeight = labelSize.y * 0.5f;screenPosition.x = Mathf.Clamp(screenPosition.x, halfWidth, Screen.width - halfWidth);screenPosition.y = Mathf.Clamp(screenPosition.y, halfHeight, Screen.height - halfHeight);}else{screenPosition = new Vector3(-1000, -1000, 0);}if (rectTransform != null){rectTransform.position = screenPosition;}UpdateVisibility(camera, globalOffset, shouldShowByDistance);}private void UpdateVisibility(Camera camera, Vector3 globalOffset, bool shouldShowByDistance){if (canvasGroup == null) return;bool shouldShow = shouldShowByDistance;if (labelTarget != null && shouldShow){bool originalDistanceCheck = labelTarget.useDistanceCheck;labelTarget.useDistanceCheck = false;shouldShow = labelTarget.ShouldShowLabel(camera, globalOffset);labelTarget.useDistanceCheck = originalDistanceCheck;}float targetAlpha = shouldShow ? 1f : 0f;canvasGroup.alpha = Mathf.Lerp(canvasGroup.alpha, targetAlpha, Time.deltaTime * 5f);canvasGroup.blocksRaycasts =false;canvasGroup.interactable = shouldShow;}public bool IsRendererVisible(bool includeInactive){if (targetRenderer == null) return false;return includeInactive || targetRenderer.enabled;}public void SetText(string text){if (textComponent != null){textComponent.text = text;}}public void SetActive(bool active){gameObject.SetActive(active);if (!active){Reset();}else if (canvasGroup != null){canvasGroup.alpha = 1f;}}public void Reset(){targetTransform = null;targetRenderer = null;labelTarget = null;if (textComponent != null){textComponent.text = "";textComponent.color = Color.white;}if (canvasGroup != null){canvasGroup.alpha = 1f;}}
}