Menu
CoddyTech

Широкая платформа

Урок 14 из 16 курса Игра в Unity: арканоид на Coddy.

Усиление Wide, пойманное платформой, расширяет её на несколько секунд. Усиление распознаёт захват: его триггерный коллайдер касается коллайдера платформы, а оба тела кинематические — этого достаточно для OnTriggerEnter. По пути вниз оно также проходит сквозь мяч, поэтому проверяет тег. Перечисление с видами усилений, заданными для каждого префаба в Inspector, позволяет отличить одно усиление от другого.

Эффект на время — это корутина: изменить, подождать, изменить обратно. Если усиление поймано повторно, пока ещё действует первое, отсчёт времени должен начаться заново, поэтому сохрани корутину, которую возвращает StartCoroutine, и останови её перед запуском новой. Иначе первая корутина завершится раньше времени и отменит действие второй. Вот ускорение:

Coroutine boost;

public void Boost()
{
    if (boost != null) StopCoroutine(boost);
    boost = StartCoroutine(BoostFor(3f));
}

IEnumerator BoostFor(float seconds)
{
    speed = normalSpeed * 2f;
    yield return new WaitForSeconds(seconds);
    speed = normalSpeed;
    boost = null;
}

Ускорение задаёт скорость относительно normalSpeed, сохранённой один раз, а не удваивает текущую скорость с последующим уменьшением вдвое: два ускорения подряд увеличили бы скорость в 4 раза. Ограничение платформы уже проверяет её ширину на каждом шаге, поэтому даже широкая платформа останавливается у стен.

challenge icon

Задание

Сложно
  1. В PowerUp добавь public enum Kind { Wide, Multiball } и public Kind kind (для каждого префаба задаётся свой тип). Добавь OnTriggerEnter: когда бонус касается объекта с тегом Paddle, бонус типа Wide вызывает Widen() у скрипта Paddle этого объекта, а бонус любого типа уничтожается.
  2. В Paddle добавь public float wideFactor = 1.6f и public float wideSeconds = 8f, а в Awake() сохрани обычную ширину платформы — её масштаб по x.
  3. Напиши public void Widen(): метод запускает корутину, которая устанавливает масштаб платформы по x равным обычной ширине, умноженной на wideFactor, ждёт wideSeconds, а затем возвращает обычную ширину. Если поймать бонус, пока платформа широкая, отсчёт времени начинается заново.

Бонус Multiball можно поймать, но пока он ничего не делает.

Нажми Play, поймай зелёный бонус, затем нажми Check.

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

using UnityEngine;
using UnityEngine.InputSystem;

public class Paddle : MonoBehaviour
{
    public float speed = 14f;
    public float wallX = 8f;   // внутренние поверхности боковых стенок находятся в точках -wallX и wallX

    Rigidbody rb;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
    }

    void FixedUpdate()
    {
        float input = 0f;
        if (Keyboard.current.leftArrowKey.isPressed || Keyboard.current.aKey.isPressed) input -= 1f;
        if (Keyboard.current.rightArrowKey.isPressed || Keyboard.current.dKey.isPressed) input += 1f;

        Vector3 target = rb.position + Vector3.right * input * speed * Time.fixedDeltaTime;
        float halfWidth = transform.localScale.x / 2f;
        target.x = Mathf.Clamp(target.x, -wallX + halfWidth, wallX - halfWidth);
        rb.MovePosition(target);
    }
}
quiz iconПроверьте себя

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

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