reckfellENGINE

RigidBody: силы, импульсы и безопасный сброс

Управление телом через физику: масса, контакты, _IntegrateForces, сон, Freeze и ориентация.

На этой странице

Выберите способ управления

RigidBody2D/3D вычисляет движение под действием сил и контактов. Для управляемого персонажа с правилами скорости/склонов часто удобнее CharacterBody. Не перемещайте динамический RigidBody присваиванием Position каждый _Process: отрисовка, интегратор и контакты начнут конкурировать за состояние.

ЗадачаМетод
Разовый толчокApplyCentralImpulse один раз на событие
Непрерывная тягаApplyCentralForce каждый нужный физический шаг
Постоянный сохраняемый вкладConstantForce / AddConstantCentralForce; явно сбрасывайте его
Толчок/сила со смещениемApplyImpulse/ApplyForce; смещение влияет на момент
Собственная интеграция или телепорт_IntegrateForces и PhysicsDirectBodyState

Сила уже интегрируется по времени; не умножайте её на delta перед ApplyCentralForce. Импульс тоже не умножается на delta и не прикладывается каждый кадр ради непрерывной тяги. Для свободного тела без сопротивления изменение скорости от центрального импульса равно impulse / mass: импульс 10 при массе 2 даёт 5 единиц/с. Контакты, ограничения и сопротивление могут изменить наблюдаемый результат.

Запустить тело и сброс

Чтобы увидеть пол, контакты и управление, используйте законченные уровни 2D и 3D. Для своего тела добавьте подходящий класс ниже, прикрепите к RigidBody2D или RigidBody3D и добавьте прямого ребёнка CollisionShape с ненулевой формой. RequestReset принимает мировую позицию. Сам запрос не меняет Transform немедленно: callback применяет его на физическом шаге и очищает скорости. Если тело заморожено, сначала снимите Freeze; запрос не является обходом режима симуляции.

LabBody2D.cs
C#
using System;
using Reckfell;

public partial class LabBody2D : RigidBody2D
{
    private Vector2? _resetPosition;
    public int ResetCount { get; private set; }
    public void RequestReset(Vector2 worldPosition)
    {
        if (!worldPosition.IsFinite()) throw new ArgumentOutOfRangeException(nameof(worldPosition));
        _resetPosition = worldPosition;
        Sleeping = false;
    }
    public override void _IntegrateForces(PhysicsDirectBodyState2D state)
    {
        if (_resetPosition is not Vector2 position) return;
        state.Transform = new Transform2D(0, position);
        state.LinearVelocity = Vector2.Zero;
        state.AngularVelocity = 0;
        _resetPosition = null;
        ResetCount++;
    }
}
LabBody3D.cs
C#
using System;
using Reckfell;

public partial class LabBody3D : RigidBody3D
{
    private Vector3? _resetPosition;
    public int ResetCount { get; private set; }
    public void RequestReset(Vector3 worldPosition)
    {
        if (!worldPosition.IsFinite()) throw new ArgumentOutOfRangeException(nameof(worldPosition));
        _resetPosition = worldPosition;
        Sleeping = false;
    }
    public override void _IntegrateForces(PhysicsDirectBodyState3D state)
    {
        if (_resetPosition is not Vector3 position) return;
        state.Transform = new Transform3D(Basis.Identity, position);
        state.LinearVelocity = Vector3.Zero;
        state.AngularVelocity = Vector3.Zero;
        _resetPosition = null;
        ResetCount++;
    }
}

Перед сбросом составного игрового объекта отдельно восстановите здоровье, таймеры и дочерние визуальные состояния. Пример сбрасывает только физическое состояние одного тела. У движущегося/повёрнутого родителя мировую позицию получите через ToGlobal. Не задавайте глобальный transform как локальный дочерний transform. ResetPhysicsInterpolation после телепорта решает визуальную интерполяцию отдельно; это не замена сброса скорости.

Контакты и состояние покоя

Для BodyEntered/BodyExited у RigidBody включите ContactMonitor и MaxContactsReported больше нуля. Лимит относится к контактам, а не обещанию такого же числа уникальных тел; одному телу могут соответствовать несколько точек. Обнаружение не означает, что нужно выключать тело прямо в callback — структурные изменения откладывайте.

Sleeping означает состояние сна симуляции, Freeze — выбранный режим заморозки. Они не равны Disabled у формы. Замороженная форма может оставаться препятствием. FreezeMode.Static и Kinematic различаются поведением при ручном перемещении; для регулярно движущейся платформы изучите AnimatableBody. Проверяйте результат на следующем физическом состоянии, а не в строке сразу после переключения режима.

CustomIntegrator отключает стандартную интеграцию сил для тела; это не способ отключить все контакты. Если он включён, рассчитывайте нужную гравитацию/силы через состояние либо осознанно вызывайте стандартную интеграцию. LockRotation запрещает обычное вращение, но не заменяет проверку геометрии и центра масс.

Повернуть к цели

Для физического поворота вычислите ошибку направления и управляйте угловой скоростью/моментом в физической фазе с ограничением скорости и коэффициентов. Непрерывный LookAt динамического тела принудительно меняет ориентацию и может ломать ожидаемую реакцию контактов. Если поворот нужен только рисунку, поверните отдельного визуального ребёнка. Отдельно учитывайте вырожденное направление, ось модели и кратчайший поворот; пример сброса намеренно восстанавливает единичную ориентацию, а не реализует сервопривод.

Если результат неожиданный

Не двигается — проверьте Freeze, Sleeping, блокировки осей, массу, фазу и фактическую силу. Нет сигнала — ContactMonitor, лимит контактов, фильтры и форма. Тело дрожит — нет ли параллельной записи Transform, стартового проникновения и крайних соотношений масс. Очень быстрый предмет проходит стену — проверьте толщину, шаг и CCD; большая масса сама по себе не исправляет дискретное обнаружение.

Документация Reckfell EngineНаверх ↑
БЫСТРЫЙ ПЕРЕХОДНачало работыEntity и иерархияC# & .NET 10Сцены и префабы
Руководства и полный API Reckfell K
reckfellENGINE
RECKFELL ACCOUNT

Вход в аккаунт

Войдите в аккаунт Reckfell.

Один аккаунт для всей платформы Reckfell.