Updates to spells, HUD, Gold, and Camera Controls. New sound effects!
This commit is contained in:
parent
689fe7be88
commit
a33d951abd
27 changed files with 578 additions and 68 deletions
|
|
@ -24,8 +24,9 @@ namespace TD.Gameplay.BuilderSpells
|
|||
/// <para><b>Server-only resolution, client-only visual.</b> <see cref="ServerCast"/> runs on
|
||||
/// the server and applies damage/status via the same <c>Physics.OverlapSphereNonAlloc</c> +
|
||||
/// <c>EnemyHealth</c>/<c>EnemyStatus</c> pattern <c>TowerCombat</c> already uses.
|
||||
/// <see cref="ClientPlayVfx"/> runs on every peer (including the server) after a successful
|
||||
/// cast, purely for presentation.</para>
|
||||
/// Presentation is split into <see cref="ClientSpawnVfx"/> (on cast) and
|
||||
/// <see cref="ClientPlayImpact"/> (on contact, <see cref="ImpactDelay"/> seconds later for a
|
||||
/// projectile spell), both running on every peer including the server.</para>
|
||||
/// </remarks>
|
||||
public abstract class BuilderSpellDefinition : ScriptableObject
|
||||
{
|
||||
|
|
@ -82,10 +83,28 @@ namespace TD.Gameplay.BuilderSpells
|
|||
public abstract bool ServerCast(ulong clientId, Vector3 targetPoint);
|
||||
|
||||
/// <summary>
|
||||
/// Runs on every peer (via <see cref="PlayerSpellLoadout"/>'s ClientRpc) after a
|
||||
/// successful <see cref="ServerCast"/>. Default no-op; override to spawn an impact VFX
|
||||
/// prefab and self-destroy it, the same idiom used elsewhere for one-off visuals.
|
||||
/// Seconds between the cast and the effect landing. 0 = instant: damage and the impact
|
||||
/// sound resolve immediately on cast. A projectile-style spell (e.g. the Fireball meteor)
|
||||
/// overrides this with its fall/travel time, so <see cref="PlayerSpellLoadout"/> spawns the
|
||||
/// visual on cast but holds <see cref="ServerCast"/> (damage) and <see cref="ClientPlayImpact"/>
|
||||
/// (sound) until the projectile reaches the ground. Set it to match the VFX's fall time.
|
||||
/// </summary>
|
||||
public virtual void ClientPlayVfx(Vector3 targetPoint) { }
|
||||
public virtual float ImpactDelay => 0f;
|
||||
|
||||
/// <summary>
|
||||
/// Runs on every peer (via <see cref="PlayerSpellLoadout"/>'s ClientRpc) the moment the
|
||||
/// spell is cast. Spawns the visual: for an instant spell that's the whole effect; for a
|
||||
/// delayed spell it's the projectile/travel visual that lands after <see cref="ImpactDelay"/>.
|
||||
/// Default no-op.
|
||||
/// </summary>
|
||||
public virtual void ClientSpawnVfx(Vector3 targetPoint) { }
|
||||
|
||||
/// <summary>
|
||||
/// Runs on every peer when the spell makes contact — immediately for an instant spell, or
|
||||
/// <see cref="ImpactDelay"/> seconds after cast for a delayed one. Play the impact sound
|
||||
/// (and any impact-moment visual) here so it lands with the effect, not the throw.
|
||||
/// Default no-op.
|
||||
/// </summary>
|
||||
public virtual void ClientPlayImpact(Vector3 targetPoint) { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,8 @@ namespace TD.Gameplay.BuilderSpells
|
|||
/// <remarks>
|
||||
/// Plain MonoBehaviour: identical on every peer (same assets), so there is nothing to sync.
|
||||
/// The server reads it to resolve casts; clients read it to resolve <see
|
||||
/// cref="BuilderSpellDefinition.ClientPlayVfx"/> and to render the cast hotbar. Mirrors
|
||||
/// cref="BuilderSpellDefinition.ClientSpawnVfx"/> / <see
|
||||
/// cref="BuilderSpellDefinition.ClientPlayImpact"/> and to render the cast hotbar. Mirrors
|
||||
/// <see cref="BuilderEffects.BuilderEffectPool"/> exactly.
|
||||
/// </remarks>
|
||||
public class BuilderSpellPool : MonoBehaviour
|
||||
|
|
|
|||
|
|
@ -28,6 +28,14 @@ namespace TD.Gameplay.BuilderSpells
|
|||
[Min(0f)]
|
||||
[SerializeField] private float impactVfxLifetime = 2f;
|
||||
|
||||
[Tooltip("Seconds from cast until the falling fireball reaches the ground. Damage and the " +
|
||||
"impact sound are held until then so they land with the visual — SET THIS TO MATCH " +
|
||||
"the meteor VFX's fall time. 0 = everything resolves instantly on cast.")]
|
||||
[Min(0f)]
|
||||
[SerializeField] private float impactDelay = 0.8f;
|
||||
|
||||
public override float ImpactDelay => impactDelay;
|
||||
|
||||
[Header("Impact Sound")]
|
||||
[Tooltip("Sound played on every peer when this spell resolves successfully. Same " +
|
||||
"SoundConfig struct TowerBuiltSound uses — reuse a tower's clip directly if " +
|
||||
|
|
@ -59,11 +67,16 @@ namespace TD.Gameplay.BuilderSpells
|
|||
return hitAny;
|
||||
}
|
||||
|
||||
public override void ClientPlayVfx(Vector3 targetPoint)
|
||||
public override void ClientSpawnVfx(Vector3 targetPoint)
|
||||
{
|
||||
// The meteor VFX plays its full fall-and-crash animation from here; it reaches the
|
||||
// ground after ImpactDelay, which is when ClientPlayImpact and ServerCast fire.
|
||||
if (impactVfxPrefab != null)
|
||||
Destroy(Instantiate(impactVfxPrefab, targetPoint, Quaternion.identity), impactVfxLifetime);
|
||||
}
|
||||
|
||||
public override void ClientPlayImpact(Vector3 targetPoint)
|
||||
{
|
||||
if (impactSound.clip != null)
|
||||
AudioManager.Instance?.Play(impactSound.clip, AudioCategory.Combat,
|
||||
impactSound.RandomPitch(), impactSound.volume);
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace TD.Gameplay.BuilderSpells
|
|||
return hitAny;
|
||||
}
|
||||
|
||||
public override void ClientPlayVfx(Vector3 targetPoint)
|
||||
public override void ClientSpawnVfx(Vector3 targetPoint)
|
||||
{
|
||||
if (areaVfxPrefab != null)
|
||||
{
|
||||
|
|
@ -70,7 +70,11 @@ namespace TD.Gameplay.BuilderSpells
|
|||
instance.transform.localScale *= Mathf.Max(Radius, 0.01f);
|
||||
Destroy(instance, EffectDuration);
|
||||
}
|
||||
}
|
||||
|
||||
public override void ClientPlayImpact(Vector3 targetPoint)
|
||||
{
|
||||
// Instant spell (ImpactDelay = 0), so this fires on cast alongside ClientSpawnVfx.
|
||||
if (areaSound.clip != null)
|
||||
AudioManager.Instance?.Play(areaSound.clip, AudioCategory.Combat,
|
||||
areaSound.RandomPitch(), areaSound.volume);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue