Menu
CoddyTech

Прицеливание платформой

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

При идеальном отскоке игрок не может прицеливаться. В играх Brick Breaker направление мяча зависит от ракетки: удар возле левого края отправляет мяч вверх и влево, а удар посередине — прямо вверх.

Преобразуй точку удара в число от -1 у левого края до 1 у правого: смещение мяча по x относительно центра ракетки, делённое на половину ширины ракетки. Ракетка шириной 4 с центром в точке x 2, удар в точке x 3: смещение равно 1, половина ширины равна 2, поэтому число равно 0.5, и мяч летит в направлении (0.5, 1, 0) после нормализации. Ограничь значение, так как мяч может коснуться угла немного за краем.

OnCollisionEnter выполняется после того, как физика рассчитала отскок, поэтому заданная там скорость заменяет его. Стены тоже отправляют мяч, но сохраняют обычный отскок, так что сначала проверь тег. collision.collider.bounds.size.x — это ширина ракетки в мировых координатах.

challenge icon

Задание

Легко

Направляй мяч с помощью платформы: угол зависит от того, где он приземлится.

  1. В Ball добавь OnCollisionEnter(Collision collision); выполняй возврат, если у объекта, с которым произошло столкновение, нет тега Paddle.
  2. Вычисли float x: разность координаты x мяча и координаты x платформы, делённую на половину collision.collider.bounds.size.x, и ограничь результат диапазоном от -1 до 1.
  3. Установи rb.linearVelocity = new Vector3(x, 1f, 0f).normalized * speed;

Нажми «Играть» и поймай мяч левым краем платформы: он отлетит влево. Затем нажми «Проверить».

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

using UnityEngine;
using UnityEngine.InputSystem;

public class Ball : MonoBehaviour
{
    public Transform paddle;
    public float speed = 9f;

    Rigidbody rb;
    bool launched;

    void Awake()
    {
        rb = GetComponent<Rigidbody>();
        PhysicsMaterial bouncy = new PhysicsMaterial("Bouncy");
        bouncy.bounciness = 1f;
        bouncy.dynamicFriction = 0f;
        bouncy.staticFriction = 0f;
        bouncy.bounceCombine = PhysicsMaterialCombine.Maximum;
        bouncy.frictionCombine = PhysicsMaterialCombine.Minimum;
        GetComponent<Collider>().material = bouncy;
    }

    void Update()
    {
        if (launched) return;
        transform.position = paddle.position + Vector3.up * 0.5f;
        if (Keyboard.current.spaceKey.wasPressedThisFrame) Launch(new Vector3(0.3f, 1f, 0f));
    }

    public void Launch(Vector3 direction)
    {
        launched = true;
        rb.linearVelocity = direction.normalized * speed;
    }

    void FixedUpdate()
    {
        if (!launched) return;
        rb.linearVelocity = rb.linearVelocity.normalized * speed;
    }
}

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

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