Unity C#

Rigidbody.velocity в Unity C# — скорость физического объекта

Rigidbody.velocity в Unity — линейная скорость физического тела, скорость изменения его позиции. Единицы — дистанция в секунду. Вектор хранит направление: компоненты X, Y и Z задают скорость по каждой из осей.

Важно для Unity 6: свойство переименовано в Rigidbody.linearVelocity. Старое имя velocity работает в версиях Unity 2023 и раньше; в новых проектах используйте новое имя, чтобы избежать предупреждений об устаревшем API.

Сигнатура и свойства

  • Vector3 velocity — читаемое и записываемое свойство.
  • В Unity единица скорости — «единица в секунду», чаще думают о метрах, но это может быть что угодно — миллиметр, световой год.
  • Установка скорости кинематическому телу запрещена и не имеет эффекта.

Главное предупреждение документации

Из docs.unity3d.com: в большинстве случаев скорость не следует менять напрямую — это приводит к нереалистичному поведению. Используйте AddForce. Не устанавливайте скорость тела на каждом шаге физики: симуляция перестанет быть правдоподобной.

Типовое оправданное применение — прыжок в шутере от первого лица, где нужен мгновенный скачок скорости без нарастания.

Пример: чтение скорости

using UnityEngine;

public class Speedometer : MonoBehaviour
{
    public Rigidbody body;

    void FixedUpdate()
    {
        // Модуль вектора скорости — скалярная скорость
        float speed = body.velocity.magnitude;
        Debug.Log("Скорость: " + speed);
    }
}

Пример: прыжок с мгновенным изменением

using UnityEngine;

public class ShooterJump : MonoBehaviour
{
    public Rigidbody body;
    public float jumpSpeed = 7f;

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space) && IsGrounded())
        {
            // Мгновенная смена вертикальной составляющей — оправданный случай
            Vector3 v = body.velocity;
            v.y = jumpSpeed;
            body.velocity = v;
        }
    }

    bool IsGrounded()
    {
        Vector3 origin = transform.position;
        Vector3 dir = Vector3.down;
        return Physics.Raycast(origin, dir, 1.1f);
    }
}

Сохраняем горизонтальные компоненты, меняем только Y: объект не «обнуляется» в воздухе. Именно так документация описывает допустимое прямое вмешательство.

Пример: ограничение скорости

using UnityEngine;

public class SpeedLimit : MonoBehaviour
{
    public Rigidbody body;
    public float maxSpeed = 12f;

    void FixedUpdate()
    {
        Vector3 v = body.velocity;
        float current = v.magnitude;

        // Clamp вернёт текущую скорость, пока она в пределах,
        // и максимум — когда тело разогналось дальше нормы
        float limited = Mathf.Clamp(current, 0f, maxSpeed);

        if (limited != current)
        {
            body.velocity = v.normalized * limited;
        }
    }
}

Обрезка скорости в FixedUpdate — компромиссный приём: он уже прямее, чем постоянная установка, но и это вмешательство в симуляцию. Для игрового «потолка скорости» часто достаточно ограничить силу, а не скорость.

velocity и скорость в кадре

Понятие Источник
Скорость физического тела Rigidbody.velocity / linearVelocity
Положение между кадрами Интерполяция Rigidbody (Interpolate)
Позиция для логики Rigidbody.position — источник истины в физике

Частые ошибки

1. Установка скорости каждый шаг

Паттерн «задал velocity = направление * скорость» в FixedUpdate убивает физику: тело не разгоняется, не тормозит, столкновения становятся искусственными. Для движения к цели есть MovePosition, для ускорения — AddForce.

2. Забытая кинематичность

Установка velocity телу с isKinematic молча ничего не делает.

3. Чтение в Update вместо FixedUpdate

Скорость обновляется на физическом шаге. Чтение в Update даёт значение, которое меняется неравномерно относительно кадров — для физической логики читайте в FixedUpdate.

4. Вертикаль, съеденная телепортом

После прямой записи transform.position у Rigidbody скорость сбрасывается. Телепорты делают через Rigidbody.position и осознанно обнуляют скорость.

5. Путаница имён в Unity 6

Код со старым velocity на новом движке выдаст предупреждение об устаревшем API. Переименование в linearVelocity сделано, чтобы отличать линейную скорость от угловой (angularVelocity).

Связанные статьи