Отбрасывание
Часть раздела Физика и игровой процесс путешествия по 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 по стрелкам, теряет эффект уже на следующем шаге, поэтому такому скрипту нужно на мгновение оставлять скорость без изменений после удара или перемещать игрока с помощью сил.
Задание
СреднеПусть игрок создаёт ударную волну клавишей Space.
- При
Input.GetKeyDown(KeyCode.Space)выполни циклforeach (Collider hit in Physics.OverlapSphere(transform.position, radius)), пропуская собственный коллайдер игрока. - Для каждого
hit.TryGetComponent(out Rigidbody body)вычислиaway = hit.transform.position - transform.position, задавaway.y = 0f. - Вызови
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
}
}
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка4Корутины
InvokeInvokeRepeating, CancelInvokeВаша первая корутинаЦиклы в корутинахОстановка корутинПовторение: обратный отсчёт10Проект: Побег с арены
АренаОхотники2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Монетная гонка
Катящийся шарСобираем монетыПотренируйтесь самостоятельно: Песочница Unity