Frost
Lesson 15 of 18 in Coddy's Unity Game: Tower Defense course.
The Frost tower barely hurts, but its shards slow an enemy down for a while. A slow is a state of one enemy, and it has an end: the enemy keeps the factor and the time the slow wears off, and works out its speed every frame from its asset's speed. While Time.time is before the end, the factor applies; after it, the enemy is back at full speed with nothing to undo. A racing car on a boost pad:
public void Boost(float multiplier, float seconds)
{
boost = multiplier;
boostUntil = Time.time + seconds;
}float speed = data.topSpeed;
if (Time.time < boostUntil)
{
speed *= boost;
}The slow must never be written into the asset. data.speed *= 0.5f would slow every enemy of that kind, the ones not spawned yet included, and nothing would ever bring the speed back. A second shard that hits a slowed enemy sets the factor and the end again, so the slow lasts while the Frost tower keeps hitting, and it does not get any stronger.
Challenge
Medium- In
TowerData, add the public floatsslowFactor(default 1: no slow) andslowDuration(default 0). FrostData sets 0.5 and 2. - In
Enemy, addpublic void Slow(float factor, float duration), which keeps the factor and the time the slow ends. Each frame the enemy walks at its asset's speed, times the factor while the slow lasts. - In
Projectile, after the damage, when the data'sslowDurationis above 0 and the target has an Enemy, slow it with the data's factor and duration.
The Frost tower is in the shop, with its FrostData asset and its FrostShard projectile. Press Play, put a Frost tower in front of your Arrows, then Check.
Try it yourself
using System;
using System.Collections.Generic;
using UnityEngine;
public class Enemy : MonoBehaviour, IDamageable
{
public static readonly List<Enemy> All = new List<Enemy>();
public static event Action<Enemy> ReachedBase;
public static event Action<Enemy> Killed;
public EnemyData data;
public Transform[] waypoints;
private int next = 1;
private int health;
void Awake()
{
health = data.maxHealth;
}
void OnEnable()
{
All.Add(this);
}
void OnDisable()
{
All.Remove(this);
}
void Update()
{
Vector3 target = waypoints[next].position;
transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
if (transform.position == target)
{
next++;
if (next == waypoints.Length)
{
ReachedBase?.Invoke(this);
Destroy(gameObject);
}
}
}
public void TakeDamage(int amount)
{
if (health <= 0)
{
return;
}
health -= amount;
if (health <= 0)
{
Killed?.Invoke(this);
Destroy(gameObject);
}
}
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.