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).