using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; /// /// 文本提示界面:外部传入文本内容和世界坐标系位置 /// public class SmallTipWin : UIBase { [SerializeField] RectTransform rectTransform; [SerializeField] RectTransform arrowImage; [SerializeField] RectTransform arrowUpImage; [SerializeField] Text descText; public static Vector3 worldPos; //世界坐标系位置 public static string showText; public static bool isDownShow = false; // 是否向下显示 protected override void OnPreOpen() { descText.text = showText; rectTransform.position = new Vector3(100, 100, 100); //初始化时,屏幕范围外 arrowImage.SetActive(!isDownShow); arrowUpImage.SetActive(isDownShow); } protected override void OnPreClose() { isDownShow = false; } protected override void OnOpen() { UpdatePos().Forget(); } async UniTask UpdatePos() { await UniTask.DelayFrame(3); // 限制在屏幕范围内 Vector3[] corners = new Vector3[4]; rectTransform.GetWorldCorners(corners); float minY = corners[0].y; float maxY = corners[0].y; for (int i = 1; i < corners.Length; i++) { if (corners[i].y < minY) minY = corners[i].y; if (corners[i].y > maxY) maxY = corners[i].y; } float screenHeight = maxY - minY; Vector2 adjustedPos = new Vector2(worldPos.x, worldPos.y + (!isDownShow ? screenHeight * 0.5f : -screenHeight * 0.5f)); Vector2 screenAdjustedPos = CameraManager.uiCamera.WorldToScreenPoint(adjustedPos); var rectWidth = rectTransform.rect.width * Screen.width / canvasScaler.referenceResolution.x; screenAdjustedPos.x = Mathf.Clamp(screenAdjustedPos.x, rectWidth * 0.5f, Screen.width - rectWidth * 0.5f); screenAdjustedPos.y = Mathf.Clamp(screenAdjustedPos.y, rectTransform.rect.height * 0.5f, Screen.height - rectTransform.rect.height * 0.5f - 15); adjustedPos = CameraManager.uiCamera.ScreenToWorldPoint(screenAdjustedPos); rectTransform.position = adjustedPos; if (!isDownShow) { rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y + 15, rectTransform.localPosition.z); } else { rectTransform.localPosition = new Vector3(rectTransform.localPosition.x, rectTransform.localPosition.y - 15, rectTransform.localPosition.z); } rectTransform.GetWorldCorners(corners); float minX = corners[0].x; float maxX = corners[0].x; for (int i = 1; i < corners.Length; i++) { if (corners[i].x < minX) minX = corners[i].x; if (corners[i].x > maxX) maxX = corners[i].x; } //显示arrowImage 的x轴上的位置,和worldPos同步,但不超过minX 和 maxX范围 if (!isDownShow) { Vector3 arrowImagePosition = arrowImage.position; arrowImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX); arrowImage.position = arrowImagePosition; } else { Vector3 arrowUpImagePosition = arrowUpImage.position; arrowUpImagePosition.x = Mathf.Clamp(worldPos.x, minX, maxX); arrowUpImage.position = arrowUpImagePosition; } } }