Menu
CoddyTech

Заморозка

Урок 21 из 25 курса Игра на Unity: Tower Defense на Coddy.

Башня Frost наносит мало урона, но её осколки на некоторое время замедляют врага. Замедление — это состояние одного врага, у которого есть время окончания: враг хранит коэффициент и время, когда замедление закончится, и каждый кадр рассчитывает свою скорость на основе скорости из данных своего объекта. Пока Time.time меньше времени окончания, применяется коэффициент; после этого враг снова движется на полной скорости, и ничего не нужно отменять. Гоночная машина на ускорительной платформе:

public void Boost(float multiplier, float seconds)
{
    boost = multiplier;
    boostUntil = Time.time + seconds;
}
float speed = data.topSpeed;
if (Time.time < boostUntil)
{
    speed *= boost;
}

Замедление ни в коем случае нельзя записывать в данные объекта. data.speed *= 0.5f замедлит всех врагов этого типа, в том числе ещё не появившихся, и скорость уже ничто не восстановит. Второй осколок, попавший в замедленного врага, снова задаёт коэффициент и время окончания, поэтому замедление действует, пока башня Frost продолжает попадать по врагу, и не становится сильнее.

challenge icon

Задание

Средне

Осколки льда на некоторое время замедляют врагов.

  1. В TowerData добавь public float slowFactor = 1f; и public float slowDuration; (для FrostData: 0.5 и 2).
  2. В Enemy метод public void Slow(float factor, float duration) сохраняет коэффициент и задаёт slowUntil = Time.time + duration; пока выполняется условие Time.time < slowUntil, враг движется со скоростью data.speed, умноженной на коэффициент.
  3. В Projectile после нанесения урона замедли цель, если data.slowDuration > 0 и у цели есть компонент Enemy.

Нажми «Играть», поставив башню Frost перед башнями Arrows: покрытые инеем Grunts будут двигаться вдвое медленнее. Затем нажми «Проверить».

Попробуйте сами

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 iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Игра на Unity: Tower Defense

Потренируйтесь самостоятельно: Песочница Unity