Unity C#

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). Без него поведение ближе к обычному обновлению позиции.

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