Прицеливание платформой
Урок 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 — это ширина ракетки в мировых координатах.
Задание
ЛегкоНаправляй мяч с помощью платформы: угол зависит от того, где он приземлится.
- В
BallдобавьOnCollisionEnter(Collision collision); выполняй возврат, если у объекта, с которым произошло столкновение, нет тегаPaddle. - Вычисли
float x: разность координаты x мяча и координаты x платформы, делённую на половинуcollision.collider.bounds.size.x, и ограничь результат диапазоном от -1 до 1. - Установи
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