Adding Text Mesh Pro, new enemies, new enemy waves, new HUD functionality, New animators, a retry function, and floating text for gold earned and lives lost.
This commit is contained in:
parent
3287e8ea43
commit
f6cc6a7102
110 changed files with 62003 additions and 251 deletions
107
Assets/_Project/Scripts/UI/FloatingTextSpawner.cs
Normal file
107
Assets/_Project/Scripts/UI/FloatingTextSpawner.cs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
// Assets/_Project/Scripts/UI/FloatingTextSpawner.cs
|
||||
using UnityEngine;
|
||||
|
||||
namespace TD.UI
|
||||
{
|
||||
/// <summary>
|
||||
/// Scene singleton that spawns <see cref="FloatingText"/> instances above
|
||||
/// world positions for gold-reward and life-loss feedback.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <b>Why a singleton:</b> the spawner is shared by every caller (kills, leaks,
|
||||
/// future status pop-ups) and holds inspector-tunable colors and a prefab
|
||||
/// reference. Plain <c>MonoBehaviour</c> — visual-only, no networking required.
|
||||
///
|
||||
/// <b>Who calls this:</b> <see cref="TD.Gameplay.WaveManager"/> invokes
|
||||
/// <see cref="SpawnGoldReward"/> and <see cref="SpawnLifeLoss"/> via ClientRpc
|
||||
/// so every peer shows the popup locally.
|
||||
///
|
||||
/// <b>Inspector setup:</b> drop this on any scene GameObject (e.g. a
|
||||
/// <c>FloatingTextSpawner</c> empty), assign the floating-text prefab, tune
|
||||
/// colors to match the HUD.
|
||||
/// </remarks>
|
||||
public class FloatingTextSpawner : MonoBehaviour
|
||||
{
|
||||
// ----- Singleton --------------------------------------------------
|
||||
|
||||
public static FloatingTextSpawner Instance { get; private set; }
|
||||
|
||||
// ----- Inspector --------------------------------------------------
|
||||
|
||||
[Tooltip("Prefab to instantiate for each pop-up. Must have a FloatingText " +
|
||||
"component and a TextMeshPro renderer.")]
|
||||
[SerializeField] private FloatingText prefab;
|
||||
|
||||
[Tooltip("Color used for kill-reward gold pop-ups. Tune to match the HUD's " +
|
||||
"gold label color.")]
|
||||
[SerializeField] private Color goldColor = new Color(1f, 0.84f, 0.2f);
|
||||
|
||||
[Tooltip("Color used for life-loss pop-ups (enemies reaching the goal).")]
|
||||
[SerializeField] private Color livesColor = new Color(0.95f, 0.25f, 0.25f);
|
||||
|
||||
[Tooltip("Default vertical offset above the source position. Tunes how high " +
|
||||
"above the enemy the text starts.")]
|
||||
[SerializeField] private float verticalOffset = 2.0f;
|
||||
|
||||
[Tooltip("Maximum random horizontal jitter applied to the spawn position so " +
|
||||
"consecutive pop-ups don't stack visually.")]
|
||||
[SerializeField] private float positionJitter = 0.4f;
|
||||
|
||||
[Tooltip("Maximum random vertical jitter applied on top of verticalOffset.")]
|
||||
[SerializeField] private float verticalJitter = 0.2f;
|
||||
|
||||
// ----- Lifecycle --------------------------------------------------
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
if (Instance != null && Instance != this)
|
||||
{
|
||||
Debug.LogWarning("[FloatingTextSpawner] Duplicate instance detected. " +
|
||||
"Only one should exist per scene.");
|
||||
return;
|
||||
}
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (Instance == this) Instance = null;
|
||||
}
|
||||
|
||||
// ----- Public API -------------------------------------------------
|
||||
|
||||
/// <summary>Spawns a gold-reward popup (e.g. "+10") at the given world position.</summary>
|
||||
public void SpawnGoldReward(Vector3 worldPos, int amount)
|
||||
=> SpawnInternal(worldPos, $"+{amount}", goldColor);
|
||||
|
||||
/// <summary>Spawns a life-loss popup (e.g. "-1") at the given world position.</summary>
|
||||
public void SpawnLifeLoss(Vector3 worldPos, int amount)
|
||||
=> SpawnInternal(worldPos, $"-{amount}", livesColor);
|
||||
|
||||
/// <summary>Lower-level overload: arbitrary content and color.</summary>
|
||||
public void SpawnCustom(Vector3 worldPos, string text, Color color)
|
||||
=> SpawnInternal(worldPos, text, color);
|
||||
|
||||
// ----- Internal ---------------------------------------------------
|
||||
|
||||
private void SpawnInternal(Vector3 worldPos, string text, Color color)
|
||||
{
|
||||
if (prefab == null)
|
||||
{
|
||||
Debug.LogWarning("[FloatingTextSpawner] No prefab assigned. " +
|
||||
"Pop-up will not be shown.");
|
||||
return;
|
||||
}
|
||||
|
||||
Vector3 jitter = new Vector3(
|
||||
Random.Range(-positionJitter, positionJitter),
|
||||
Random.Range(0f, verticalJitter),
|
||||
Random.Range(-positionJitter, positionJitter));
|
||||
|
||||
Vector3 spawnPos = worldPos + Vector3.up * verticalOffset + jitter;
|
||||
|
||||
var instance = Instantiate(prefab, spawnPos, Quaternion.identity);
|
||||
instance.Init(text, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue