// Assets/_Project/Scripts/UI/FloatingText.cs using TMPro; using UnityEngine; namespace TD.UI { /// /// One-shot world-space text that floats upward and fades out, then destroys itself. /// Spawned by for kill-reward and life-loss feedback. /// /// /// Prefab setup: a GameObject with a TextMeshPro (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. /// 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; /// Sets content and color. Call once immediately after Instantiate. public void Init(string content, Color color) { if (text == null) text = GetComponentInChildren(); 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); } } }