Отбрасывание
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 54 из 63.
Отбрасывание — это толчок от того, что в вас попало: один импульс вдоль линии от того, кто ударил, к тому, в кого попали. Этот бампер отбрасывает всё, что в него врезается:
[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 в соответствии с клавишами со стрелками, потеряет этот импульс на следующем шаге. Поэтому такой скрипт должен на мгновение оставлять скорость без изменений после удара или перемещать игрока с помощью сил.
Задание
СреднеИгрок может создавать ударную волну. Напиши скрипт Shockwave для Player. В Inspector задай для него radius (4), power (6) и lift (2). Скрипт Player готов: стрелки перемещают игрока.
- При нажатии Space найди все коллайдеры в пределах
radiusот игрока с помощьюPhysics.OverlapSphere. - Каждый из них, у которого есть Rigidbody, кроме самого игрока, получает импульс:
powerнаправленной от игрока по земле, плюсliftвверх. - Коллайдеры без Rigidbody, например земля, остаются нетронутыми.
Нажми Play, пройдись среди ящиков и нажми Space, затем Check.
Попробуйте сами
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 для физикиСкоростьКинематические телаПовторение: пусковая площадка2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Погоня за монетами
Катящийся мячМонеты для сбора