using TMPro; using UnityEngine; public class Billboard : MonoBehaviour { private GameObject _parent; public string defaultText = "Sample Text"; public TMP_Text tmpText; public Canvas canvas; public string prefix = ""; private Camera _camera; public LineRenderer lineRenderer; public Transform lineStart; private GameObject _lineEndObject; private MeshFilter _lineEndMeshFilter; private void Start() { _camera = Camera.main; lineRenderer = GetComponent(); _parent = transform.parent.gameObject; transform.SetParent(null); tmpText.text = defaultText; } private void LateUpdate() { if (canvas.enabled) transform.position = _parent.transform.position + (_camera.transform.up * 0.1f); if (!lineRenderer.enabled) return; lineRenderer.SetPosition(0, lineStart.position); lineRenderer.SetPosition(1, CalculateLineEndPosition()); } private void SetText(string txt) { tmpText.text = prefix + txt; } private void ShowCanvas() { canvas.enabled = true; lineRenderer.enabled = true; } private void HideCanvas() { canvas.enabled = false; lineRenderer.enabled = false; } public void ShowHint(string txt) { ShowCanvas(); SetText(txt); } public void HideHint() { HideCanvas(); } public void SetLineTarget(GameObject newGM) { _lineEndObject = newGM; _lineEndMeshFilter = _lineEndObject.GetComponent(); } private Vector3 CalculateLineEndPosition() { if (_lineEndObject == null) { lineRenderer.enabled = false; return Vector3.zero; } return _lineEndMeshFilter == null ? _lineEndObject.transform.position : FindClosestVertexToTargetPoint(lineStart.position, _lineEndMeshFilter); } private Vector3 FindClosestVertexToTargetPoint(Vector3 start, MeshFilter filter) { // Get the Mesh object from the MeshFilter component Mesh mesh = filter.mesh; // Get the world position of the point you want to find the closest point on the mesh to // Transform the point into local space relative to the MeshFilter's transform Vector3 localPoint = filter.transform.InverseTransformPoint(start); // Find the closest vertex to the point float closestDistance = Mathf.Infinity; Vector3 closestVertex = Vector3.zero; for (int i = 0; i < mesh.vertexCount; i++) { Vector3 vertex = mesh.vertices[i]; float distance = Vector3.Distance(localPoint, vertex); if (distance < closestDistance) { closestDistance = distance; closestVertex = vertex; } } // Transform the closest vertex back into world space return filter.transform.TransformPoint(closestVertex); } }