Attention: Here be dragons
This is the latest
(unstable) version of this documentation, which may document features
not available in or compatible with released stable versions of Godot.
Checking the stable version of the documentation...
Використання RigidBody
Що таке тверде тіло?
Тверде тіло – це тіло, яким безпосередньо керує фізичний механізм, щоб імітувати поведінку фізичних об’єктів. Щоб визначити форму тіла, воно повинно мати один або кілька призначених об’єктів Shape3D. Зауважте, що встановлення положення цих форм впливатиме на центр мас тіла.
Як керувати rigid body
Поведінка твердого тіла може бути змінена шляхом встановлення його властивостей, таких як маса та вага. Фізичний матеріал потрібно додати до твердого тіла, щоб відрегулювати його тертя та відскок, і встановити, чи воно абсорбуюче та/або грубе. Ці властивості можна встановити в інспекторі або за допомогою коду. Перегляньте RigidBody3D і PhysicsMaterial для повного переліку властивостей та їхніх ефектів.
Існує кілька способів керування рухом твердого тіла залежно від бажаного застосування.
Якщо вам потрібно розмістити тверде тіло лише один раз, наприклад, щоб встановити його початкове положення, ви можете скористатися методами, що надаються вузлом Node3D, такими як set_global_transform() або look_at(). Однак ці методи не можна викликати кожного кадру, інакше фізичний движок не зможе правильно змоделювати стан тіла. Як приклад, розглянемо тверде тіло, яке ви хочете повернути так, щоб воно було спрямоване на інший об'єкт. Поширеною помилкою під час реалізації такої поведінки є використання look_at() кожного кадру, що порушує фізичну симуляцію. Нижче ми продемонструємо, як це правильно реалізувати.
Той факт, що ви не можете використовувати методи set_global_transform() або look_at(), не означає, що ви не можете мати повний контроль над твердим тілом. Натомість ви можете контролювати це за допомогою зворотного виклику _integrate_forces(). У цьому методі ви можете додати сили, застосувати імпульси або встановити швидкість, щоб досягти будь-якого руху, який ви бажаєте.
Метод «подивитися»
Як описано вище, використання методу look_at() Node3D не може використовуватися в кожному кадрі для відстеження цілі. Ось користувацький метод look_at() під назвою look_follow(), який працюватиме з твердими тілами:
extends RigidBody3D
var speed: float = 0.1
func look_follow(state: PhysicsDirectBodyState3D, current_transform: Transform3D, target_position: Vector3) -> void:
var forward_local_axis: Vector3 = Vector3(1, 0, 0)
var forward_dir: Vector3 = (current_transform.basis * forward_local_axis).normalized()
var target_dir: Vector3 = (target_position - current_transform.origin).normalized()
var local_speed: float = clampf(speed, 0, acos(forward_dir.dot(target_dir)))
if forward_dir.dot(target_dir) > 1e-4:
state.angular_velocity = local_speed * forward_dir.cross(target_dir) / state.step
func _integrate_forces(state):
var target_position = $my_target_node3d_node.global_transform.origin
look_follow(state, global_transform, target_position)
using Godot;
public partial class MyRigidBody3D : RigidBody3D
{
private float _speed = 0.1f;
private void LookFollow(PhysicsDirectBodyState3D state, Transform3D currentTransform, Vector3 targetPosition)
{
Vector3 forwardLocalAxis = new Vector3(1, 0, 0);
Vector3 forwardDir = (currentTransform.Basis * forwardLocalAxis).Normalized();
Vector3 targetDir = (targetPosition - currentTransform.Origin).Normalized();
float localSpeed = Mathf.Clamp(_speed, 0.0f, Mathf.Acos(forwardDir.Dot(targetDir)));
if (forwardDir.Dot(targetDir) > 1e-4)
{
state.AngularVelocity = forwardDir.Cross(targetDir) * localSpeed / state.Step;
}
}
public override void _IntegrateForces(PhysicsDirectBodyState3D state)
{
Vector3 targetPosition = GetNode<Node3D>("MyTargetNode3DNode").GlobalTransform.Origin;
LookFollow(state, GlobalTransform, targetPosition);
}
}
Цей метод використовує властивість angular_velocity твердого тіла для обертання тіла. Вісь, навколо якої потрібно обертатися, визначається перехресним добутком між поточним напрямком вперед і напрямком, у якому потрібно дивитися. Затискач — це простий метод, який використовується для запобігання виходу обертання за межі потрібного напрямку слід розглядати, оскільки загальна величина необхідного обертання визначається аркосинусом скалярного добутку. Цей метод також можна використовувати з axis_lock_angular_*. Якщо потрібен більш точний контроль, можуть знадобитися такі рішення, як ті, що покладаються на class_Quaternion, як описано в Використання 3D перетворень.