Физика — Bodies, Collision, Jolt
StaticBody3D, RigidBody3D, CharacterBody3D, Area3D — и почему с 4.6 физика стала быстрее.
С Godot 4.6 физикой по умолчанию для 3D стал Jolt — высокопроизводительный движок, используемый в Death Stranding 2 и других AAA-играх. Старый Godot Physics остался как опция и продолжает быть default для 2D.
Это значит: предсказуемая, масштабируемая 3D-физика из коробки. Никаких сторонних движков интегрировать не нужно.
Четыре класса тел
Узлы-наследники CollisionObject3D, образующие физический объект:
| Узел | Когда |
|---|---|
| StaticBody3D | Не движется. Стены, пол, статичная архитектура. |
| AnimatableBody3D | Двигается через анимацию или скрипт. Толкает RigidBody3D. Аналог Unity Kinematic Rigidbody. |
| RigidBody3D | Полная динамика — гравитация, силы, импульсы, столкновения с реакцией. |
| CharacterBody3D | Кинематика для персонажа: вы задаёте velocity, движок двигает с учётом коллизий. Единственный узел с move_and_slide(). |
Также:
- Area3D — невидимая область с триггерами
body_entered/area_entered. Аналог Unity Collider сisTrigger=true. - PhysicalBone3D — для рэгдоллов внутри Skeleton3D.
- SoftBody3D — мягкие тела (ткань, флаги, простые желейные объекты). Использует mesh-based soft-body simulation; работает и с Godot Physics, и с Jolt (с некоторыми ограничениями).
CollisionShape3D — форма для физики
В отличие от Unity, где collider — это компонент на том же GameObject, в Godot CollisionShape3D
— это отдельный дочерний узел. У него свойство shape: Shape3D — ресурс, описывающий форму:
RigidBody3D (Player)
├── MeshInstance3D (визуальный mesh)
└── CollisionShape3D
└── shape: CapsuleShape3D (height=2, radius=0.4)
Виды Shape3D:
- BoxShape3D, SphereShape3D, CapsuleShape3D, CylinderShape3D — примитивы. Дёшево.
- ConvexPolygonShape3D — выпуклый mesh. Для динамических объектов сложной формы.
- ConcavePolygonShape3D — произвольный mesh (триангуляция). Только для статики.
- HeightMapShape3D — рельеф из 2D-карты высот.
Просто добавьте несколько дочерних CollisionShape3D — все станут shape’ами этого тела. Удобно для составных коллайдеров (например, машина: корпус + бампер).
CharacterBody3D — главный для платформера/FPS
CharacterBody3D хранит velocity: Vector3 и метод move_and_slide(), который пытается
переместить тело на velocity * delta с учётом столкновений: останавливается, скользит вдоль стен,
опускается по уклонам, поднимается на ступеньки.
extends CharacterBody3D
@export var speed: float = 5.0
@export var jump_velocity: float = 6.0
func _physics_process(delta: float) -> void:
# Гравитация — из настроек проекта (Project Settings → Physics → 3D → Default Gravity)
# get_gravity() возвращает Vector3(0, -9.8, 0) по умолчанию
if not is_on_floor():
velocity += get_gravity() * delta
# Прыжок
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# Горизонтальное движение
var input_dir := Input.get_vector("move_left", "move_right", "move_forward", "move_back")
var direction := (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * speed
velocity.z = direction.z * speed
else:
velocity.x = move_toward(velocity.x, 0, speed)
velocity.z = move_toward(velocity.z, 0, speed)
move_and_slide()
Полезные методы и свойства CharacterBody3D:
is_on_floor(),is_on_wall(),is_on_ceiling()— простые проверки контакта.get_floor_normal()— нормаль пола, на котором стоим.floor_max_angle— максимальный угол склона, считающегося полом (по умолчанию 45°).floor_snap_length— на какую глубину “примагнитить” к полу при сходе по склону (избегает отскоков на спусках).get_slide_collision_count()+get_slide_collision(i)— детали столкновений за этот тик.
Свой 3D без движка: считаете next_pos = pos + velocity * dt, ловите коллизии руками. Сложно
и багги.
CharacterController.Move(motion) ↔ move_and_slide(). CharacterBody3D мощнее: автоматически
скользит по стенам, поднимается на ступеньки, прижимается к склонам — всё настраивается
флажками.
RigidBody3D — динамика
Для физических объектов, реагирующих на силы (мяч, ящик, dropped item):
extends RigidBody3D
func _ready() -> void:
mass = 2.0
linear_damp = 0.5
func explode_push(direction: Vector3, force: float) -> void:
apply_central_impulse(direction * force)
Методы:
apply_force(force: Vector3, position: Vector3 = Vector3.ZERO)— постоянная сила (в_physics_process).apply_central_force(force)— сила в центр массы.apply_impulse(impulse, position)— мгновенный импульс.apply_central_impulse(impulse)— мгновенный импульс в центр массы.apply_torque_impulse(impulse)— крутящий момент.
Свойства:
mass: float— масса.gravity_scale: float— множитель гравитации (0 = нет, 1 = нормально).linear_damp/angular_damp— затухание.freeze/freeze_mode— заморозить.lock_rotation: bool— запретить вращение.continuous_cd: CCDMode—DISABLED/CAST_RAY/CAST_SHAPE— для быстрых тел против туннелирования.
Area3D — триггеры
Area3D — не физическое тело, но генерирует сигналы при пересечении с другими CollisionObject3D:
extends Area3D
func _ready() -> void:
body_entered.connect(_on_body_entered)
area_entered.connect(_on_area_entered)
func _on_body_entered(body: Node3D) -> void:
if body.is_in_group("player"):
print("Player picked up coin")
queue_free()
func _on_area_entered(area: Area3D) -> void:
print("Another area overlapped: ", area.name)
Сигналы Area3D:
body_entered(body)/body_exited(body)— физическое тело вошло/вышло.area_entered(area)/area_exited(area)— другая Area3D.body_shape_entered,area_shape_entered— детализированные с индексами shape’ов.
Collision Layers и Masks
У каждого CollisionObject3D два битфилда:
- Collision Layer — на каких слоях находится этот объект.
- Collision Mask — какие слои этот объект сканирует (с кем пересекается / реагирует).
Чтобы A замечал B: маска A должна содержать слой(и) B. Чтобы взаимодействие было двусторонним, маска B тоже должна содержать слой A.
Имена слоёв настраиваются в Project Settings → Layer Names → 3D Physics.
В Unity матрица слоёв двунаправленная. В Godot — два независимых битфилда на каждом объекте. Это даёт больше гибкости (например, “пуля видит врага, но не наоборот”), но требует осторожности.
Jolt vs Godot Physics
С 4.6 Jolt — default для новых проектов 3D. Существующие проекты автоматически не переключаются — выставьте в Project Settings → Physics → 3D → Physics Engine.
| Параметр | Godot Physics | Jolt |
|---|---|---|
| Производительность с 1000+ телами | Деградирует | Стабильна |
| Stacking (стопки ящиков) | Может проседать | Лучше |
| CCD (continuous) | Есть | Есть, лучше |
| Doubleside thin colliders | Иногда баги | Стабильно |
| Joints | Базовые | Полный набор |
Если у вас уже работающий проект на Godot Physics — оставайтесь. Для нового — Jolt.
В следующей главе — камера и Phantom Camera.