Menu
CoddyTech

Отбрасывание

Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 57 из 71.

Отбрасывание — это толчок в сторону от того, что вас ударило: один импульс вдоль линии от ударившего объекта к тому, в который он попал. Этот бампер отбрасывает всё, что в него врезается:

[SerializeField] private float power = 8f;

void OnCollisionEnter(Collision collision)
{
    Vector3 away = collision.transform.position - transform.position;
    away.y = 0f;
    collision.rigidbody.AddForce(away.normalized * power, ForceMode.Impulse);
}

collision.transform.position - transform.position указывает от бампера к объекту, который в него врезался. Значение y устанавливается в 0, чтобы толчок оставался горизонтальным, а normalized задаёт вектору одинаковую длину независимо от расстояния между центрами объектов. ForceMode.Impulse — это разовый толчок: он сразу изменяет скорость на величину power, делённую на массу, поэтому мяч массой 2 отлетит вдвое медленнее мяча массой 1. Режим по умолчанию ForceMode.Force предназначен для применения на каждом шаге и даёт эффект за один шаг — в 50 раз меньше.

Толчок действует, только пока ничто не перезаписывает скорость. Игрок, у которого FixedUpdate на каждом шаге задаёт rb.linearVelocity по стрелкам, теряет эффект уже на следующем шаге, поэтому такому скрипту нужно на мгновение оставлять скорость без изменений после удара или перемещать игрока с помощью сил.

challenge icon

Задание

Средне

Пусть игрок создаёт ударную волну клавишей Space.

  1. При Input.GetKeyDown(KeyCode.Space) выполни цикл foreach (Collider hit in Physics.OverlapSphere(transform.position, radius)), пропуская собственный коллайдер игрока.
  2. Для каждого hit.TryGetComponent(out Rigidbody body) вычисли away = hit.transform.position - transform.position, задав away.y = 0f.
  3. Вызови body.AddForce(away.normalized * power + Vector3.up * lift, ForceMode.Impulse);.

Нажми «Играть» и нажми Space рядом с ящиками. Затем нажми «Проверить».

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

using UnityEngine;

public class Shockwave : MonoBehaviour
{
    [SerializeField] private float radius = 4f;
    [SerializeField] private float power = 6f;
    [SerializeField] private float lift = 2f;

    void Update()
    {
        // При нажатии Space: оттолкнуть от игрока каждый Rigidbody в пределах radius
    }
}

Все уроки раздела Физика и игровой процесс

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