Использование RigidBody

Что такое твёрдое тело?

Твёрдое тело — это тело, которое непосредственно управляется физическим движком для моделирования поведения физических объектов. Для определения формы тела ему должен быть назначен один или несколько объектов Shape. Обратите внимание, что установка положения этих форм повлияет на центр масс тела.

Как управлять твёрдым телом

Поведение жесткого тела можно изменить, задав его свойства, такие как масса и вес. Чтобы настроить трение и отскок, а так же установить, является ли он поглощающим и/или твёрдым, к твёрдому телу необходимо добавить физический материал. Эти свойства можно задать в инспекторе или с помощью кода. Полный список свойств и их эффектов см. в разделах RigidBody и PhysicsMaterial.

Существует несколько способов управления движением твёрдого тела в зависимости от потребности приложения.

Если Вам нужно поместить твёрдое тело только один раз, например, чтобы задать его начальное местоположение, Вы можете использовать методы, предоставляемые узлом Spatial, такие как set_global_transform() или look_at(). Однако, эти методы нельзя вызывать каждый кадр, иначе физический движок не сможет правильно смоделировать состояние тела. В качестве примера рассмотрим твёрдое тело, которое Вы хотите повернуть так, чтобы оно указывало на другой объект. Распространенной ошибкой при реализации такого поведения является использование look_at() каждый кадр, что нарушает физическую симуляцию. Ниже мы покажем, как правильно реализовать это.

Тот факт, что Вы не можете использовать методы set_global_transform() или look_at(), не означает, что вы не можете иметь полный контроль над твёрдым телом. Вместо этого можно управлять им с помощью обратного вызова _integrate_forces (). В этом методе можно добавлять силы, прикладывать импульсы, или задавать скорость для достижения любого нужного движения.

Метод «look at»

Как описано выше, метод look_at() узла Spatial нельзя использовать каждый кадр для следования за целью. Вот пользовательский метод look_at (), который будет надежно работать с твёрдыми телами:

extends RigidBody

func look_follow(state, current_transform, target_position):
    var up_dir = Vector3(0, 1, 0)
    var cur_dir = current_transform.basis.xform(Vector3(0, 0, 1))
    var target_dir = (target_position - current_transform.origin).normalized()
    var rotation_angle = acos(cur_dir.x) - acos(target_dir.x)

    state.set_angular_velocity(up_dir * (rotation_angle / state.get_step()))

func _integrate_forces(state):
    var target_position = $my_target_spatial_node.get_global_transform().origin
    look_follow(state, get_global_transform(), target_position)

Этот метод использует метод твёрдого тела set_angular_velocity() для поворота. Сначала вычисляется разность между текущим и требуемым углом, а затем добавляется скорость, необходимая для поворота на эту величину за одно время кадра.

Примечание

Этот скрипт не будет работать с твёрдыми телами в режиме персонажа, потому что в этом случае поворот тела заблокирован. Вместо этого необходимо повернуть присоединенный узел сетки с помощью стандартных методов Spatial.