Проверка земли с помощью луча
Часть раздела Физика и игровой процесс путешествия по Unity на Coddy. Урок 37 из 71.
Прыжок должен начинаться только с земли. В примере «Стояние на земле» это определялось по нормалям контакта, которые обновлялись сообщениями о столкновениях. Луч сразу отвечает на вопрос «стою ли я на чём-нибудь?» в любой момент: направь его строго вниз от центра, сделав немного длиннее расстояния от центра до нижней точки. Этот игрок — капсула высотой 2 единицы, поэтому нижняя точка находится на 1 единицу ниже центра, а длина луча равна 1.1:
public float jumpForce = 5f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space) && IsGrounded())
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
bool IsGrounded()
{
return Physics.Raycast(transform.position, Vector3.down, 1.1f);
}Дополнительные 0.1 — это запас. Тело, покоящееся на полу, может оказаться чуть выше него или немного погрузиться в него, поэтому луч длиной ровно 1 в некоторые кадры не попадёт в пол. Слишком большая длина приводит к обратной проблеме: при длине 3 игрок сможет снова прыгнуть, находясь в воздухе на высоте 2 единиц, а при нулевой длине луч всегда будет находить пол, поэтому каждое нажатие будет приводить к прыжку.
Луч начинается внутри собственного коллайдера игрока, который лучи игнорируют, поэтому он никогда не сообщает об игроке. Клавиша считывается в Update(), потому что GetKeyDown имеет значение true только в течение одного кадра, а одиночный импульс можно добавить прямо там, как в примере «Прыжок с импульсом».
Задание
СреднеПусть лягушка прыгает только с земли.
- Добавь
bool IsGrounded(), которая возвращаетPhysics.Raycast(transform.position, Vector3.down, 0.85f): радиус лягушки, 0.75, плюс 0.1. - В
Update()добавь&& IsGrounded()кifдля клавиши пробела.
Нажми «Играть» и дважды нажми пробел: лягушка прыгнет один раз. Затем нажми «Проверить».
Попробуйте сами
using UnityEngine;
public class Hopper : MonoBehaviour
{
public float jumpForce = 6f;
private Rigidbody rb;
void Start()
{
rb = GetComponent<Rigidbody>();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
rb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
}
}
}
Все уроки раздела Физика и игровой процесс
1Твёрдое тело
Гравитация и массаТолкаем с помощью AddForceПрыжок с импульсомFixedUpdate для физикиСкоростьКинематические телаПовторение: пусковая площадка4Корутины
InvokeInvokeRepeating, CancelInvokeВаша первая корутинаЦиклы в корутинахОстановка корутинПовторение: обратный отсчёт10Проект: Побег с арены
АренаОхотники2Столкновения
OnCollisionEnterВо что я попал?Разрушение при столкновенииСтояние на землеОтскок и трениеФормы коллайдеровПовторение: разрушаемая стена5Проект: Монетная гонка
Катящийся шарСобираем монетыПотренируйтесь самостоятельно: Песочница Unity