Godot 4.6 ใช้ Jolt เป็นฟิสิกส์ 3D ค่าเริ่มต้น: โปรเจกต์ เก่าต้องย้ายเองไหม
Godot 4.6 ตั้ง Jolt Physics ให้โปรเจกต์ 3D ใหม่ แต่โปรเจกต์เดิมยังใช้ GodotPhysics3D อยู่ บทความนี้อธิบายพฤติกรรมที่ต่าง ค่าที่ต้องรู้ และวิธีย้ายพร้อมทดสอบ
- Godot 4.6 (26 ม.ค. 2026) เขียน physics/3d/physics_engine = Jolt Physics ลงในโปรเจกต์ใหม่ โปรเจกต์เดิมไม่เปลี่ยน
- ค่า DEFAULT ตอนนี้เท่ากับ GodotPhysics3D แต่เอกสารบอกว่าอาจเปลี่ยนในอนาคต ตั้งค่าให้ชัดในโปรเจกต์ที่ส่งงานแล้ว
- Jolt ต่างจากเดิมใน joint ที่มี body เดียว, collision margin, การแก้วัตถุซ้อนกัน, ray-cast face index และขนาดของ WorldBoundaryShape3D
- ย้ายบน branch แยก รันฉากที่มีฟิสิกส์ทุกฉาก แล้วเทียบผลด้วยตัวเลข ไม่ใช่ด้วยตา
Godot 4.6 ออกเมื่อ 26 มกราคม 2026 และเปลี่ยนเรื่องใหญ่หนึ่งเรื่องให้เกม 3D คือ Jolt Physics เป็นเอนจินฟิสิกส์ค่าเริ่มต้นของโปรเจกต์ 3D ใหม่ แทน GodotPhysics3D ที่ใช้มาตลอด สิ่งที่หลายคนเข้าใจผิดคือคิดว่าโปรเจกต์เก่าจะย้ายตามให้เอง ซึ่งไม่ใช่ บทความนี้อธิบายกลไกจริง พฤติกรรมที่ต่าง และขั้นตอนย้ายแบบที่วัดผลได้
ข้อมูลตรวจกับหน้า release ของ Godot 4.6, เอกสาร Using Jolt Physics (stable), ProjectSettings.xml ของแท็ก 4.6-stable และ PR #105737 ที่ทำให้ Jolt เป็นค่าเริ่มต้น ณ ตุลาคม 2026 (ตอนนี้มี 4.7 แล้ว แต่การเปลี่ยนนี้เริ่มที่ 4.6)
เปลี่ยนอะไร และไม่เปลี่ยนอะไร
ดู PR #105737 จะเห็นว่า Godot ไม่ได้เปลี่ยนค่าเริ่มต้นของ setting แต่ให้ project manager เขียนบรรทัดนี้ลง project.godot ตอนสร้างโปรเจกต์ใหม่
[physics]
3d/physics_engine="Jolt Physics"
ส่วนค่าเริ่มต้นของ physics/3d/physics_engine ยังเป็น DEFAULT และเอกสาร ProjectSettings ของ 4.6 เขียนว่า DEFAULT ตอนนี้เท่ากับ GodotPhysics3D แต่อาจเปลี่ยนในรุ่นหน้า ให้เลือกตัวที่ระบุชัดถ้าอยากให้โปรเจกต์อยู่กับเอนจินเดิม
| สถานการณ์ | ใน project.godot | เอนจินที่ได้ใน 4.6 |
|---|---|---|
| สร้างโปรเจกต์ใหม่ใน 4.6+ | "Jolt Physics" | Jolt |
| โปรเจกต์เก่า ไม่เคยแตะค่านี้ | ไม่มีบรรทัด → DEFAULT | GodotPhysics3D (อาจเปลี่ยนในอนาคต) |
| โปรเจกต์เก่า เลือก GodotPhysics3D ไว้ | "GodotPhysics3D" | GodotPhysics3D |
touch project.godot แล้วเปิด editor | editor เติม "Jolt Physics" ให้ | Jolt |
เกม 3D ที่ส่งงานแล้วและยังไม่ย้าย ให้ตั้ง
GodotPhysics3Dให้ชัดวันนี้ จะได้ไม่ถูกเปลี่ยนเอนจินเงียบ ๆ ตอนอัปเกรดรุ่นถัดไป
พฤติกรรมที่ต่างจาก GodotPhysics3D
เอกสาร Using Jolt Physics ระบุไว้ตรง ๆ ข้อที่เจอในเกมจริงบ่อยที่สุดคือ
- Joint ที่มี body เดียว ถ้าใส่ body ไว้แค่ node เดียวของ joint อีกฝั่งจะถือเป็น “โลก” Jolt กับ GodotPhysics3D ตีความฝั่งต่างกัน ทำให้ limit ของ joint กลับด้าน แก้ด้วย
physics/jolt_physics_3d/joints/world_nodeหรือย้าย body ไปอีกช่อง - property ของ joint บางตัวไม่รองรับ เช่น
bias,softness,relaxationของ HingeJoint3D และ soft limit ของ Generic6DOFJoint3D ตั้งค่าไม่ใช่ค่าเริ่มต้นจะได้ warning - Collision margin Jolt ใช้ “convex radius” หด shape ก่อนแล้วขยายกลับ ขนาดรวมไม่โต แต่มุมจะมน (GodotPhysics3D ไม่ใช้ margin เลย)
- วัตถุซ้อนกัน GodotPhysics3D ดันออกเหมือนสปริง อาจเด้งเกิน Jolt แก้เฉพาะตำแหน่ง ไม่เด้งเกิน แต่ใช้เวลานานกว่า
- ray-cast
face_indexคืน-1เสมอจนกว่าจะเปิดqueries/enable_ray_cast_face_index - RigidBody3D ที่ freeze แบบ kinematic ไม่รายงาน contact กับ static/kinematic body จนกว่าจะเปิด
simulation/generate_all_kinematic_contacts - Area3D กับ SoftBody3D Jolt ยิง
body_enteredให้ soft body ด้วย GodotPhysics3D ไม่ยิง - WorldBoundaryShape3D ไม่ได้ไม่มีขอบเขตอีกต่อไป
ตัวอย่างคำนวณ: สามค่าที่เปลี่ยนเกมเงียบ ๆ
1. พื้นแบบ WorldBoundaryShape3D หายเมื่อเดินไกล
physics/jolt_physics_3d/limits/world_boundary_shape_size ค่าเริ่มต้น 2000.0 คือ plane อยู่กลางกล่องขนาด 2000 m
- ครึ่งหนึ่งของ 2000 = 1000
- วัตถุที่อยู่ห่างจากจุดกลางเกิน 1000 m ในแนวระนาบจะไม่ชนพื้นนี้ เกม open world หรือเกมวิ่งไม่รู้จบที่ใช้ plane เป็นพื้น จะเห็นตัวละครร่วงทะลุพื้นเมื่อไปไกลพอ
2. มุมกล่องมน
collision_margin_fraction ค่าเริ่มต้น 0.08 คูณแกนที่สั้นที่สุดของ shape โดยมี Shape3D.margin (ค่าเริ่มต้น 0.04) เป็นเพดาน
- กล่อง 2 × 0.5 × 1 m → 0.08 × 0.5 = 0.04 m → ไม่เกินเพดาน margin = 4 cm
- กล่อง 0.2 × 0.2 × 0.2 m → 0.08 × 0.2 = 1.6 cm มุมมน 4 cm บนลังขนาดคน มองไม่ออก แต่ถ้าเกมต้องวางกล่องซ้อนกันเป๊ะ ๆ หรือให้ลูกบอลกลิ้งตกขอบโต๊ะ จะเห็นความต่าง
3. วัตถุซ้อนกันหลุดออกช้าแค่ไหน (แบบจำลองง่าย คิดเฉพาะ Baumgarte)
baumgarte_stabilization_factor ค่าเริ่มต้น 0.2 = แก้ 20% ของระยะซ้อนต่อ step
- ซ้อนกัน 10 cm เหลือ 10 × 0.8ⁿ cm หลัง n step
- ต้องการเหลือ < 1 cm → 0.8ⁿ < 0.1 → n > ln 0.1 ÷ ln 0.8 ≈ 10.3 → 11 step
- ที่
physics_ticks_per_second= 60 → 11 × 16.7 ms ≈ 183 ms ตัวละครที่ spawn ซ้อนกำแพงจะค่อย ๆ ไหลออกราวหนึ่งในห้าวินาที ไม่ดีดกระเด็น
ย้ายโปรเจกต์เก่าทีละขั้น
- แตก branch ใน git ก่อน การเปลี่ยนเอนจินแก้แค่บรรทัดเดียว ย้อนกลับง่าย
- Project Settings > Physics > 3D > Physics Engine เลือก
Jolt Physicsกด Save & Restart - อ่าน Output หา warning เรื่อง joint property ที่ไม่รองรับ แก้ตามรายการ
- ไล่ joint ที่มี body เดียว ทุกตัว ดูว่า limit กลับด้านไหม
- ค้นโค้ดที่ใช้
face_index,get_contact_impulse(), Area3D กับ soft body แล้วตัดสินใจว่าจะเปิด setting ไหน - รันทุกฉากที่มีฟิสิกส์ 4.6 เพิ่มปุ่มปรับความเร็วเกมใน editor ใช้ชะลอดูจังหวะชน
- วัดด้วยตัวเลข เขียนฉากทดสอบเล็ก ๆ ที่ปล่อยวัตถุแล้วบันทึกตำแหน่งตามเวลา เทียบสองเอนจิน
# test_drop.gd — แนบกับ RigidBody3D แล้วรันทั้งสองเอนจิน เทียบผล
extends RigidBody3D
var _ticks := 0
func _physics_process(_delta: float) -> void:
_ticks += 1
var hz := Engine.physics_ticks_per_second
if _ticks % (hz / 2) == 0: # พิมพ์ทุกครึ่งวินาที นับ tick ไม่ใช่บวก float
print("%.2f s y=%.3f vy=%.3f" % [float(_ticks) / hz, global_position.y, linear_velocity.y])
if _ticks >= hz * 3:
get_tree().quit()
ถ้าเกมขึ้นกับ timing ของฟิสิกส์มาก อ่าน game loop แบบ fixed timestep ประกอบ เพราะ _physics_process เดินตาม tick คงที่ 60 ครั้งต่อวินาทีโดยค่าเริ่มต้นไม่ว่าเอนจินไหน
ข้อผิดพลาดที่เจอบ่อย
- คิดว่าอัปเกรดเป็น 4.6 แล้วได้ Jolt โปรเจกต์เก่ายังเป็น DEFAULT = GodotPhysics3D
- ปล่อยไว้เป็น DEFAULT วันที่ DEFAULT เปลี่ยน เกมจะเปลี่ยนเอนจินโดยไม่มีใครตั้งใจ ตั้งค่าให้ชัด
- ตั้ง collision margin fraction เป็น 0 เพื่อให้ขอบคม เอกสารเตือนว่าค่าใกล้ 0 ทำให้การชนของ convex shape แม่นน้อยลง
- ใช้
get_contact_impulse()คำนวณดาเมจ ใน Jolt เป็นค่าประมาณล่วงหน้า แม่นเฉพาะเมื่อสองวัตถุไม่แตะวัตถุอื่น - ย้ายจาก extension Godot Jolt แล้วใช้ชื่อ setting เดิม หมวดย้ายจาก
physics/jolt_3dเป็นphysics/jolt_physics_3dหลายค่าเปลี่ยนจากเปอร์เซ็นต์เป็นเศษส่วน - เปิด Run On Separate Thread เอกสารบอกว่ายังทดสอบน้อย ถือเป็น experimental
แหล่งอ้างอิง
คำถามที่พบบ่อย
เปิดโปรเจกต์ 4.5 ใน 4.6 แล้วจะได้ Jolt อัตโนมัติไหม
ไม่ ประกาศ 4.6 บอกว่าโปรเจกต์เดิมไม่ได้รับผลกระทบ เฉพาะโปรเจกต์ที่สร้างใหม่ใน 4.6 ขึ้นไปเท่านั้นที่มีบรรทัดตั้ง Jolt เขียนไว้ใน project.godot
ฟิสิกส์ 2D เปลี่ยนด้วยไหม
ไม่ การเปลี่ยนนี้เป็นของ 3D เท่านั้น ค่าที่เกี่ยวคือ physics/3d/physics_engine ฝั่ง 2D แยกตั้งค่าคนละตัว
ยังใช้ extension Godot Jolt ตัวเดิมได้ไหม
ได้ แต่เอกสารบอกว่าอยู่ในโหมดดูแลรักษา ตัวที่ฝังใน Godot ตั้งแต่ 4.4 เป็นตัวหลัก ชื่อ project setting ย้ายจาก physics/jolt_3d ไป physics/jolt_physics_3d และ joint node แบบ Jolt ของ extension ไม่มีในตัวฝัง
คำสั่งและค่าตั้งในบทความทดสอบบนระบบตัวอย่าง ลองบนเครื่องทดสอบก่อนใช้กับระบบจริงเสมอ