Заморозка
Урок 15 из 18 курса Игра в Unity: защита башен на 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 продолжает попадать по врагу, и не становится сильнее.
Задание
Средне- В
TowerDataдобавь публичные поля типа floatslowFactor(по умолчанию 1: замедления нет) иslowDuration(по умолчанию 0). В FrostData установи значения 0.5 и 2. - В
Enemyдобавьpublic void Slow(float factor, float duration), которая сохраняет коэффициент и время окончания замедления. Каждый кадр враг движется со скоростью своего ресурса, умноженной на коэффициент, пока длится замедление. - В
Projectileпосле нанесения урона замедли цель с коэффициентом и длительностью из данных, еслиslowDurationв данных больше 0 и цель является Enemy.
Башня Frost есть в магазине, вместе с ресурсом FrostData и снарядом FrostShard. Нажми Play, поставь башню Frost перед своими Arrows, затем нажми Check.
Попробуйте сами
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);
}
}
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.