Rigidbody.MovePosition в Unity C# — перемещение через физику
Rigidbody.MovePosition в Unity — перемещение Rigidbody к заданной позиции с учётом настроек интерполяции. Метод рассчитан на кинематические тела: он даёт плавный переход между кадрами и корректно работает с Rigidbody interpolation.
Сигнатура
Rigidbody.MovePosition(Vector3 position)— позиция в мировых координатах.- Возвращает
void. Вызов — это запрос на перемещение, а не мгновенная установка координаты.
Как работает — из документации Unity
- MovePosition двигает Rigidbody и учитывает настройки интерполяции: при включённой интерполяции тело плавно переходит между кадрами.
- Unity перемещает Rigidbody при каждом вызове FixedUpdate.
- Позиция задаётся в мировых координатах.
- Для телепорта используйте Rigidbody.position, а не MovePosition — метод сделан для плавного движения.
Пример: движение лифта
using UnityEngine;
public class Elevator : MonoBehaviour
{
public Rigidbody body;
public Transform[] floors;
public float speed = 2f;
private int current = 0;
void FixedUpdate()
{
Vector3 target = floors[current].position;
Vector3 here = body.position;
// Шаг за физическое обновление
Vector3 next = Vector3.MoveTowards(here, target, speed * Time.fixedDeltaTime);
// Запрос перемещения кинематического тела
body.MovePosition(next);
// Когда тело доехало до этажа, MovePosition вернёт саму цель —
// расстояние станет нулевым
float remaining = Vector3.Distance(next, target);
if (remaining == 0f)
{
// Этаж достигнут — ждём команды Call
}
}
public void Call(int index)
{
// Clamp не даёт индексу выйти за границы массива этажей
current = Mathf.Clamp(index, 0, floors.Length - 1);
}
}
Здесь соединились два принципа: шаг считается через Vector3.MoveTowards с Time.fixedDeltaTime (постоянная скорость, независимая от кадров), а применение идёт через MovePosition — тело едет плавно и уважает интерполяцию.
Пример: вращение прицела с плавной догонкой
using UnityEngine;
public class PlatformFollower : MonoBehaviour
{
public Rigidbody body;
public Transform platform;
public float smooth = 6f;
void FixedUpdate()
{
// Платформа двигается — кинематическое тело догоняет её
Vector3 desired = platform.position;
float t = Time.fixedDeltaTime * smooth;
Vector3 next = Vector3.Lerp(body.position, desired, t);
body.MovePosition(next);
}
}
MovePosition или transform.position
| Критерий | MovePosition |
transform.position |
|---|---|---|
| Тип тела | Рассчитан на кинематический Rigidbody | Любое, но нарушает физику у не-кинематических |
| Интерполяция | Учитывается — движение плавное | Игнорируется — возможны рывки |
| Момент применения | На физическом шаге (FixedUpdate) | Сразу |
| Взаимодействие с другими телами | Корректно толкает то, что стоит на пути | Тело «проходит сквозь» препятствия |
Частые ошибки
1. MovePosition вместо телепорта
Метод двигает тело плавно. Телепорт через него будет выглядеть как медленный перелёт. Для мгновенного перемещения — Rigidbody.position.
2. Вызов в Update
Перемещение рассчитано на FixedUpdate: в Update оно применяется непредсказуемо относительно физического шага и интерполяции.
3. Мировые вместо локальных координат
Аргумент всегда в мире. Для движения относительно родителя сначала переводите точку через TransformPoint.
4. Забытая интерполяция тела
Плавность MovePosition раскрывается только при включенном режиме Interpolation у Rigidbody (Interpolate). Без него поведение ближе к обычному обновлению позиции.