Menu
CoddyTech

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 icon

Challenge

Medium
  1. In TowerData, add the public floats slowFactor (default 1: no slow) and slowDuration (default 0). FrostData sets 0.5 and 2.
  2. In Enemy, add public 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.
  3. In Projectile, after the damage, when the data's slowDuration is 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);
        }
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Unity Game: Tower Defense