Adding VFX package, cleaning up texture on terrain slightly, and adding new build FX asset for orbital drop visuals.

This commit is contained in:
Matt F 2026-06-30 22:22:58 -07:00
parent 2fbee5fd99
commit 28b0e2cdf2
24 changed files with 15522 additions and 10 deletions

View file

@ -3,6 +3,7 @@ using Unity.Netcode;
using UnityEngine;
using TD.Core;
using TD.Towers;
using TD.VFX;
namespace TD.Gameplay
{
@ -69,6 +70,13 @@ namespace TD.Gameplay
"Leave empty to fall back to the legacy cube Y-scale growth below.")]
[SerializeField] private ConstructionPhaseSet defaultPhaseSet;
[Header("Drop reticle FX")]
[Tooltip("Optional targeting-reticle effect (ground decal + beam + motes) shown for the " +
"life of this build. Spawned as a child on every peer and fed construction " +
"progress each frame so it shrinks as the tower builds, then destroyed with " +
"this visual at completion/cancel. Leave empty to build with no reticle.")]
[SerializeField] private TowerDropReticle dropReticlePrefab;
[Header("Construction stages (cube fallback)")]
[Tooltip("FALLBACK ONLY (no phase set assigned): number of discrete growth stages " +
"while constructing. 4 = 1/4 → 2/4 → 3/4 → 4/4 height.")]
@ -247,6 +255,10 @@ namespace TD.Gameplay
private int activePhaseIndex = -1;
private bool usePhases;
// Spawned child targeting-reticle effect (local, all peers). Fed progress in Update;
// destroyed automatically with this NetworkObject at completion/cancel.
private TowerDropReticle dropReticleInstance;
// ----- Lifecycle --------------------------------------------------
/// <summary>
@ -299,6 +311,15 @@ namespace TD.Gameplay
// cube). Depends on towerTypeId, which is replicated by now on every peer.
ResolvePhaseSet();
// Spawn the targeting-reticle FX as a local child. It reads this build site's
// replicated progress (fed in Update) and dies with us at completion/cancel.
if (dropReticlePrefab != null)
{
dropReticleInstance = Instantiate(dropReticlePrefab, transform);
dropReticleInstance.transform.localPosition = Vector3.zero;
dropReticleInstance.transform.localRotation = Quaternion.identity;
}
// Subscribe to value changes so visual updates are reactive.
currentStage.OnValueChanged += HandleStageChanged;
@ -353,6 +374,13 @@ namespace TD.Gameplay
private void Update()
{
// Drive the targeting reticle on every peer, every stage: 0 while Queued
// (full-size reticle, awaiting a builder), shrinking while Constructing, frozen
// while Paused. Kept before the Constructing early-return so it also animates
// the queued/paused states.
if (dropReticleInstance != null)
dropReticleInstance.SetProgress(ComputeProgressNormalized());
// While constructing, advance the visual based on server time. Runs on every
// peer so visuals stay synchronized. Paused does NOT update — the visual is
// frozen at the pause point.