75 lines
2.6 KiB
C#
75 lines
2.6 KiB
C#
// Assets/_Project/Scripts/UI/FloatingText.cs
|
|
using TMPro;
|
|
using UnityEngine;
|
|
|
|
namespace TD.UI
|
|
{
|
|
/// <summary>
|
|
/// One-shot world-space text that floats upward and fades out, then destroys itself.
|
|
/// Spawned by <see cref="FloatingTextSpawner"/> for kill-reward and life-loss feedback.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// <b>Prefab setup:</b> a GameObject with a <c>TextMeshPro</c> (3D, NOT TextMeshProUGUI)
|
|
/// component as a child or root, this script, and no Canvas required — TMP renders in
|
|
/// world space natively. The text auto-billboards toward the main camera each frame.
|
|
///
|
|
/// Lifetime, float speed, and fade are tuned on the prefab. The spawner only sets
|
|
/// content + color.
|
|
/// </remarks>
|
|
public class FloatingText : MonoBehaviour
|
|
{
|
|
[Tooltip("The TextMeshPro component that renders the text. Auto-located in children " +
|
|
"if left empty.")]
|
|
[SerializeField] private TMP_Text text;
|
|
|
|
[Tooltip("World units per second the text drifts upward.")]
|
|
[SerializeField] private float floatSpeed = 1.5f;
|
|
|
|
[Tooltip("Seconds the text remains visible before the GameObject is destroyed.")]
|
|
[SerializeField] private float lifetime = 1.2f;
|
|
|
|
private float elapsed;
|
|
private Color baseColor;
|
|
|
|
/// <summary>Sets content and color. Call once immediately after Instantiate.</summary>
|
|
public void Init(string content, Color color)
|
|
{
|
|
if (text == null) text = GetComponentInChildren<TMP_Text>();
|
|
if (text != null)
|
|
{
|
|
text.text = content;
|
|
text.color = color;
|
|
}
|
|
baseColor = color;
|
|
elapsed = 0f;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
elapsed += Time.deltaTime;
|
|
if (elapsed >= lifetime)
|
|
{
|
|
Destroy(gameObject);
|
|
return;
|
|
}
|
|
|
|
// Drift upward.
|
|
transform.position += Vector3.up * floatSpeed * Time.deltaTime;
|
|
|
|
// Fade alpha linearly from 1 → 0 over the lifetime.
|
|
if (text != null)
|
|
{
|
|
float alpha = 1f - (elapsed / lifetime);
|
|
var c = baseColor;
|
|
c.a = alpha;
|
|
text.color = c;
|
|
}
|
|
|
|
// Billboard to the main camera. Using the camera's forward (rather than
|
|
// position-difference) keeps the text upright even when the camera tilts.
|
|
var cam = Camera.main;
|
|
if (cam != null)
|
|
transform.rotation = Quaternion.LookRotation(cam.transform.forward);
|
|
}
|
|
}
|
|
}
|