Толкаем предметы
Часть раздела Создание настоящих игр путешествия по Unity на Coddy. Урок 40 из 56.
CharacterController никогда ничего не толкает: если направить его на ящик с Rigidbody, он остановится, словно наткнулся на стену. Вместо этого Unity вызывает OnControllerColliderHit(ControllerColliderHit hit) в скриптах самого контроллера для каждого коллайдера, которого касается Move, включая пол, а скрипт решает, что произойдёт. hit.collider — это то, чего коснулись, hit.moveDirection — направление Move, при котором произошло касание, а hit.normal — направление, в котором обращена поверхность в точке контакта. Вот скрипт толкания от самой Unity:
public float pushPower = 2f;
void OnControllerColliderHit(ControllerColliderHit hit)
{
Rigidbody body = hit.collider.attachedRigidbody;
if (body == null || body.isKinematic) return; // нечего толкать
if (hit.moveDirection.y < -0.3f) return; // он находится у нас под ногами
Vector3 pushDir = new Vector3(hit.moveDirection.x, 0f, hit.moveDirection.z);
body.linearVelocity = pushDir * pushPower;
}У каждого return есть причина. У пола и стен нет Rigidbody, поэтому для них body равен null, и с ними происходит касание почти при каждом Move. Кинематическое тело движется, только когда его перемещает собственный скрипт, поэтому скорость на него не действует. Если Move направлен круто вниз, значит, он коснулся чего-то под ногами, и ящик, на котором стоит игрок, не следует толкать.
Направление толчка учитывает только x и z, поэтому ящик скользит по земле, а не вдавливается в неё. Установка linearVelocity вместо приложения силы перемещает лёгкий и тяжёлый ящики с одинаковой скоростью; body.AddForce(pushDir * pushPower, ForceMode.Impulse) толкал бы тяжёлый ящик слабее.
Задание
СреднеПинайте мячи по двору. Игрок перемещается с помощью CharacterController (Walker.cs, уже готов). Напишите Kicker.cs и также добавьте его к объекту Player. В Inspector задайте значения kickPower (6) и lift (4).
- Когда игрок врезается в тело, которое можно толкнуть, задайте его
linearVelocityв направлении движения — параллельно земле, умножив наkickPower, — и добавьтеliftстрого вверх, чтобы мяч летел вперёд и вверх. - У земли и столба нет Rigidbody: пропускайте их без ошибки.
- Мяч под ногами игрока не пинается.
Нажмите Играть и пните красный мяч, затем нажмите Проверить.
Попробуйте сами
using UnityEngine;
public class Kicker : MonoBehaviour
{
public float kickPower = 6f;
public float lift = 4f;
// Отталкивать мячи, с которыми сталкивается игрок
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Создание настоящих игр
1Текст на экране
Холст и текстПокажем счётФорматирование чиселТаймер обратного отсчётаПовторение: спидометр4Сцены и уровни
Загрузить сценуПерезапустить уровеньСледующий уровеньСохранить между сценамиПовторение: выбор уровня7Управление временем
Пауза с timeScaleЗамедленное движениеНемасштабируемое времяПовторение: Bullet Time10Проект: 3D-платформер
ТрассаДвижущиеся платформы2Кнопки и экраны
Кнопки и onClickЛямбдыСвязи в InspectorВключение и выключение панелейШкалы здоровьяПовторение: магазин улучшений5Сохранение с помощью PlayerPrefs
Сохранение числаЗагрузка со значением по умолчаниюРекордСохранение настроекПовторение: монеты в банке8Контроллер персонажа
CharacterController.MoveГравитация вручнуюПрыжкиТолкаем предметыДвижение в направлении взглядаПовторение: двойной прыжок