Menu
CoddyTech

Толкаем предметы

Часть раздела Создание настоящих игр путешествия по 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) толкал бы тяжёлый ящик слабее.

challenge icon

Задание

Средне

Пинайте мячи по двору. Игрок перемещается с помощью 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;

    // Отталкивать мячи, с которыми сталкивается игрок
}
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Создание настоящих игр