107 lines
3.0 KiB
C#
107 lines
3.0 KiB
C#
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 = "<mark=#000000BB>";
|
|
private Camera _camera;
|
|
|
|
public LineRenderer lineRenderer;
|
|
public Transform lineStart;
|
|
|
|
private GameObject _lineEndObject;
|
|
private MeshFilter _lineEndMeshFilter;
|
|
|
|
private void Start()
|
|
{
|
|
_camera = Camera.main;
|
|
lineRenderer = GetComponent<LineRenderer>();
|
|
_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<MeshFilter>();
|
|
}
|
|
|
|
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);
|
|
}
|
|
} |