示例:利用UGUI的Text显示角色名称
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary> /// 角色头顶名字 /// </summary> public class UIHeadText : MonoBehaviour { [SerializeField] private Text m_Text; [SerializeField] private Outline outline; public Transform target; //文字要跟随的目标 public Vector3 offset; //文字偏移量 private RectTransform rectTransform; void Awake() { if (rectTransform == null) rectTransform = this.GetComponent<RectTransform>(); } void Update() { if (target == null || target.gameObject == null) return; //Screen Space - Overlay 渲染模式下屏幕坐标与世界坐标等价 //屏幕左下角为(0, 0),右上角为(Screen.width, Screen.height) Vector3 position = target.position + offset; Vector3 screenPoint = Camera.main.WorldToScreenPoint(position); rectTransform.anchoredPosition = screenPoint; } public string Text { get { return m_Text.text; } set { m_Text.text = value; } } public Color TextColor { get { return m_Text.color; } set { m_Text.color = value; } } public Color OutlineColor { get { if (outline == null) return Color.white; return outline.effectColor; } set { if (outline == null) return; outline.effectColor = value; } } }
效果
第二版
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; /// <summary> /// 玩家头顶信息 (跟随玩家移动) /// </summary> public class UIHeadInfo : GameEventBehaviour { [SerializeField] private RectTransform rectTransform; [SerializeField] private Text nameText; [SerializeField] private Vector3 offset; public Transform target; public float scaleFactor = 1; protected override void OnIDestroy() { target = null; } protected override void OnUpdate() { if (target == null || target.gameObject == null) return; //Screen Space - Overlay 渲染模式下屏幕坐标与世界坐标等价 //屏幕左下角为(0, 0),右上角为(Screen.width, Screen.height) Vector3 position = target.position + offset; Vector3 screenPoint = Camera.main.WorldToScreenPoint(position); Vector3 pos = screenPoint / scaleFactor; pos.x = Mathf.Ceil(pos.x); pos.y = Mathf.Ceil(pos.y); pos.z = Mathf.Ceil(pos.z); rectTransform.anchoredPosition = pos; } public void SetName(string name) { nameText.text = name; } // 创建头顶信息, target: 要跟随的目标 public static UIHeadInfo Create(Transform target) { GameObject canvas = GameObject.FindGameObjectWithTag("Canvas"); if (canvas == null) { Debug.LogError("Canvas not found, failed to create UIHeadInfo."); return null; } Canvas canvas_com = canvas.GetComponent<Canvas>(); GameObject go = Resources.Load<GameObject>("UI/Prefab/UIHeadInfo"); go = GameObject.Instantiate<GameObject>(go); go.transform.SetParent(canvas.transform); go.transform.localPosition = Vector3.zero; go.transform.localRotation = Quaternion.identity; go.transform.localScale = Vector3.one; UIHeadInfo headInfo = go.GetComponent<UIHeadInfo>(); headInfo.target = target; headInfo.scaleFactor = canvas_com.scaleFactor; return headInfo; } }
// 世界坐标转屏幕坐标 public Vector3 WorldToScreenPoint(Vector3 worldPos) { //屏幕坐标系原点在左下角 Vector3 pos = Camera.main.WorldToScreenPoint(worldPos); //Canvas坐标原点在屏幕中心 //与Canvas坐标原点对齐 pos.x -= canvas.pixelRect.width / 2; pos.y -= canvas.pixelRect.height / 2; //适配不同分辨率 pos = pos / canvas.scaleFactor; //去掉小数,避免抖动 pos.x = Mathf.Ceil(pos.x); pos.y = Mathf.Ceil(pos.y); pos.z = Mathf.Ceil(pos.z); return pos; }