GPUParticles2D/3D ใน Godot 4 — คู่มือฉบับสมบูรณ์
1. บทนำ
Godot 4 ใช้ GPUParticles2D และ GPUParticles3D เป็นโหนดระบบพาร์ติเคิลเริ่มต้น โหนดเหล่านี้ทำงานบน GPU ทั้งหมด ทำให้เร็วกว่าเวอร์ชัน CPU อย่างมากเมื่อมีพาร์ติเคิลจำนวนมาก ParticlesMaterial แบบเดิมจาก Godot 3 ถูกแทนที่ด้วย ParticleProcessMaterial ซึ่งควบคุมพฤติกรรมของพาร์ติเคิลได้ละเอียดกว่า
CPUParticles2D และ CPUParticles3D ยังคงมีอยู่ในฐานะโหนดสำรองสำหรับอุปกรณ์ที่ไม่รองรับ GPU compute หรือเมื่อคุณต้องเข้าถึงข้อมูลพาร์ติเคิลแต่ละตัวจาก GDScript สำหรับการใช้งานส่วนใหญ่ พาร์ติเคิลแบบ GPU เป็นตัวเลือกที่แนะนำ
2. GPUParticles2D vs CPUParticles2D
| คุณสมบัติ | GPUParticles2D | CPUParticles2D |
|---|---|---|
| การประมวลผล | GPU (compute shader) | CPU (เธรดหลัก) |
| จำนวนพาร์ติเคิลสูงสุด | 100,000+ ได้อย่างมีประสิทธิภาพ | ในทางปฏิบัติจำกัดที่ ~1,000-5,000 |
| Sub-emitter | รองรับ | ไม่รองรับ |
| Trail | รองรับ | ไม่รองรับ |
| การเข้าถึงพาร์ติเคิลแต่ละตัว | ไม่ได้ (GPU เท่านั้น) | ได้ (จาก GDScript) |
| โหมด Compatibility | ต้องใช้ Vulkan/Metal/D3D12 | ทำงานได้ทุกที่ |
| ประเภทมาเทเรียล | ParticleProcessMaterial | พรอเพอร์ตีในตัว (ไม่ต้องใช้มาเทเรียล) |
GPUParticles2D เป็นค่าเริ่มต้น สลับไปใช้ CPUParticles2D เฉพาะเมื่อคุณต้องรองรับ Compatibility renderer, ต้องอ่านตำแหน่งพาร์ติเคิลใน GDScript หรือกำหนดเป้าหมายเป็นฮาร์ดแวร์เก่ามาก ๆ
3. การตั้งค่าพื้นฐาน
ในการสร้างเอฟเฟกต์พาร์ติเคิลพื้นฐาน ให้เพิ่มโหนด GPUParticles2D ลงในซีนของคุณแล้วกำหนด ParticleProcessMaterial ให้กับมัน นี่คือการตั้งค่าขั้นต่ำใน GDScript:
# Create a GPUParticles2D node via code var particles = GPUParticles2D.new() particles.amount = 50 particles.lifetime = 2.0 particles.explosiveness = 0.0 # 0 = continuous, 1 = all at once particles.randomness = 0.5 # Create and assign the material var mat = ParticleProcessMaterial.new() mat.direction = Vector3(0, -1, 0) # Note: uses Vector3 even in 2D mat.initial_velocity_min = 50.0 mat.initial_velocity_max = 100.0 mat.gravity = Vector3(0, 98, 0) particles.process_material = mat add_child(particles)
พรอเพอร์ตีสำคัญบนโหนด GPUParticles2D เอง:
amount— จำนวนพาร์ติเคิลที่มีชีวิตอยู่ในเวลาใดเวลาหนึ่ง (ค่าเริ่มต้น: 8)lifetime— ระยะเวลาที่พาร์ติเคิลแต่ละตัวมีชีวิตอยู่ เป็นวินาที (ค่าเริ่มต้น: 1.0)one_shot— ปล่อยครั้งเดียวแล้วหยุด (ค่าเริ่มต้น: false)explosiveness— 0.0 = ปล่อยต่อเนื่อง, 1.0 = ปล่อยพาร์ติเคิลทั้งหมดพร้อมกันrandomness— ออฟเซ็ตแบบสุ่มของจังหวะการปล่อย (0.0-1.0)speed_scale— ตัวคูณสำหรับความเร็วในการจำลองemitting— ระบบกำลังปล่อยพาร์ติเคิลอยู่หรือไม่
4. เจาะลึก ParticleProcessMaterial
ParticleProcessMaterial ควบคุมพฤติกรรมของพาร์ติเคิลแต่ละตัวตลอดช่วงชีวิตของมัน พรอเพอร์ตีเชิงทิศทางทั้งหมดใช้ Vector3 แม้แต่กับพาร์ติเคิล 2D (องค์ประกอบ Z จะถูกละเว้นไป)
ทิศทางและความเร็ว
var mat = ParticleProcessMaterial.new() # Direction: normalized vector for initial particle heading mat.direction = Vector3(0, -1, 0) # Upward in 2D (Y is flipped) # Spread: cone angle in degrees (0 = straight line, 180 = hemisphere) mat.spread = 45.0 # Initial velocity: particles spawn with speed in this range mat.initial_velocity_min = 100.0 mat.initial_velocity_max = 200.0 # Gravity: constant acceleration applied every frame mat.gravity = Vector3(0, 98, 0) # Pulls downward in 2D
ความเร็วเชิงมุม
หมุนพาร์ติเคิลขณะเคลื่อนที่ มีประโยชน์สำหรับเศษซาก, กระดาษเสี้ยว หรือใบไม้
mat.angular_velocity_min = -180.0 # degrees per second mat.angular_velocity_max = 180.0
การเปลี่ยนสเกลตลอดช่วงชีวิต
ใช้ CurveTexture เพื่อเปลี่ยนขนาดพาร์ติเคิลตลอดช่วงชีวิตของมัน:
var curve = Curve.new() curve.add_point(Vector2(0.0, 1.0)) # Full size at birth curve.add_point(Vector2(0.5, 1.2)) # Slightly larger at midlife curve.add_point(Vector2(1.0, 0.0)) # Shrink to nothing at death var curve_tex = CurveTexture.new() curve_tex.curve = curve mat.scale_curve = curve_tex
Damping และ Attractor
Damping ทำให้พาร์ติเคิลช้าลงเมื่อเวลาผ่านไป จำลองแรงต้านอากาศ ส่วน attractor (โหนดแยกต่างหาก) ดึงพาร์ติเคิลเข้าหาจุดหนึ่ง
mat.damping_min = 5.0 mat.damping_max = 10.0
5. การไล่สี
พรอเพอร์ตี color_ramp บน ParticleProcessMaterial รับค่า GradientTexture1D เพื่อเปลี่ยนสีพาร์ติเคิลอย่างราบรื่นตลอดช่วงชีวิตของมัน สิ่งนี้จำเป็นสำหรับเอฟเฟกต์ไฟ, ควัน และเวทมนตร์ที่สมจริง
ตัวอย่างการไล่สีของไฟ
var gradient = Gradient.new()
gradient.colors = PackedColorArray([
Color(1.0, 1.0, 1.0, 1.0), # White (hot core)
Color(1.0, 1.0, 0.2, 1.0), # Yellow
Color(1.0, 0.5, 0.0, 1.0), # Orange
Color(0.8, 0.1, 0.0, 0.8), # Red
Color(0.2, 0.0, 0.0, 0.0), # Dark red, transparent (fade out)
])
gradient.offsets = PackedFloat32Array([0.0, 0.15, 0.4, 0.7, 1.0])
var grad_tex = GradientTexture1D.new()
grad_tex.gradient = gradient
mat.color_ramp = grad_tex
คุณยังตั้งค่าพรอเพอร์ตี color แบบเรียบแทนการไล่สีได้ สำหรับพาร์ติเคิลสีเดียวสม่ำเสมอ:
mat.color = Color(0.2, 0.6, 1.0, 0.8) # Semi-transparent blue
6. รูปทรงการปล่อย
รูปทรงการปล่อยกำหนดว่าพาร์ติเคิลจะเกิดขึ้นที่ใด ตั้งค่าผ่าน emission_shape บน ParticleProcessMaterial
Point
พาร์ติเคิลทั้งหมดเกิดขึ้นที่จุดกำเนิดของโหนด เป็นรูปทรงเริ่มต้น
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_POINT
Sphere / Sphere Surface
พาร์ติเคิลเกิดขึ้นแบบสุ่มภายในทรงกลม (หรือบนพื้นผิวของมันเท่านั้น)
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_SPHERE mat.emission_sphere_radius = 50.0 # Surface only: mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_SPHERE_SURFACE mat.emission_sphere_radius = 50.0
Box
พาร์ติเคิลเกิดขึ้นแบบสุ่มภายในปริมาตรทรงสี่เหลี่ยม
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_BOX mat.emission_box_extents = Vector3(100, 10, 0) # Wide and thin
Ring
พาร์ติเคิลเกิดขึ้นบนรูปทรงวงแหวน (โดนัท) กำหนดด้วยรัศมีใน/นอกและความสูง
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_RING mat.emission_ring_radius = 80.0 # Outer radius mat.emission_ring_inner_radius = 60.0 # Inner radius (hole) mat.emission_ring_height = 0.0 # Flat ring mat.emission_ring_axis = Vector3(0, 0, 1) # Ring normal
EMISSION_SHAPE_BOX ที่มี X กว้างและ Y แคบ เพื่อสร้างเอฟเฟกต์ระดับพื้นดิน เช่น รอยฝุ่นหรือพาร์ติเคิลรอยเท้า
7. สูตรใช้งานจริง
ไฟ
ไล่สีส้ม-แดง, ความเร็วขึ้นบน, การกระจายเล็กน้อย, สเกลลดลงตลอดช่วงชีวิต
func create_fire() -> GPUParticles2D:
var p = GPUParticles2D.new()
p.amount = 40
p.lifetime = 0.8
p.randomness = 0.3
var mat = ParticleProcessMaterial.new()
mat.direction = Vector3(0, -1, 0)
mat.spread = 15.0
mat.initial_velocity_min = 40.0
mat.initial_velocity_max = 80.0
mat.gravity = Vector3(0, -20, 0) # Slight upward pull
mat.damping_min = 5.0
mat.damping_max = 10.0
# Color ramp: white -> yellow -> orange -> red -> transparent
var grad = Gradient.new()
grad.colors = PackedColorArray([
Color(1, 1, 1, 1), Color(1, 1, 0.2, 1),
Color(1, 0.4, 0, 0.9), Color(0.6, 0.1, 0, 0.4),
Color(0.2, 0, 0, 0)
])
grad.offsets = PackedFloat32Array([0.0, 0.1, 0.35, 0.7, 1.0])
var grad_tex = GradientTexture1D.new()
grad_tex.gradient = grad
mat.color_ramp = grad_tex
# Scale: shrink over time
var curve = Curve.new()
curve.add_point(Vector2(0, 0.8))
curve.add_point(Vector2(0.3, 1.0))
curve.add_point(Vector2(1, 0.0))
var curve_tex = CurveTexture.new()
curve_tex.curve = curve
mat.scale_curve = curve_tex
p.process_material = mat
return p
ควัน
ไล่สีเทา, ลอยขึ้นช้า ๆ, กระจายกว้าง, alpha ต่ำเพื่อให้ดูจาง
func create_smoke() -> GPUParticles2D:
var p = GPUParticles2D.new()
p.amount = 25
p.lifetime = 3.0
p.randomness = 0.5
var mat = ParticleProcessMaterial.new()
mat.direction = Vector3(0, -1, 0)
mat.spread = 35.0
mat.initial_velocity_min = 10.0
mat.initial_velocity_max = 30.0
mat.gravity = Vector3(0, -5, 0)
mat.damping_min = 2.0
mat.damping_max = 5.0
mat.angular_velocity_min = -30.0
mat.angular_velocity_max = 30.0
var grad = Gradient.new()
grad.colors = PackedColorArray([
Color(0.6, 0.6, 0.6, 0.0), Color(0.5, 0.5, 0.5, 0.3),
Color(0.4, 0.4, 0.4, 0.2), Color(0.3, 0.3, 0.3, 0.0)
])
grad.offsets = PackedFloat32Array([0.0, 0.15, 0.6, 1.0])
var grad_tex = GradientTexture1D.new()
grad_tex.gradient = grad
mat.color_ramp = grad_tex
# Scale: grow over time (smoke expands)
var curve = Curve.new()
curve.add_point(Vector2(0, 0.3))
curve.add_point(Vector2(0.5, 1.0))
curve.add_point(Vector2(1, 1.5))
var curve_tex = CurveTexture.new()
curve_tex.curve = curve
mat.scale_curve = curve_tex
p.process_material = mat
return p
ฝน
เส้นขาว-น้ำเงิน, แรงโน้มถ่วงลงแรง, กระจายแคบ, จำนวนพาร์ติเคิลมาก
func create_rain() -> GPUParticles2D:
var p = GPUParticles2D.new()
p.amount = 200
p.lifetime = 1.0
# Use a box emission to cover the screen width
var mat = ParticleProcessMaterial.new()
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_BOX
mat.emission_box_extents = Vector3(600, 0, 0)
mat.direction = Vector3(0.05, 1, 0) # Slightly angled
mat.spread = 3.0
mat.initial_velocity_min = 400.0
mat.initial_velocity_max = 500.0
mat.gravity = Vector3(0, 200, 0)
var grad = Gradient.new()
grad.colors = PackedColorArray([
Color(0.7, 0.8, 1.0, 0.6), Color(0.7, 0.85, 1.0, 0.4),
Color(0.7, 0.85, 1.0, 0.0)
])
grad.offsets = PackedFloat32Array([0.0, 0.8, 1.0])
var grad_tex = GradientTexture1D.new()
grad_tex.gradient = grad
mat.color_ramp = grad_tex
# Stretch particles to look like streaks
mat.scale_min = 0.5
mat.scale_max = 0.5
p.process_material = mat
return p
ประกายไฟ
เหลือง-ส้ม, ระเบิดพุ่งกระจาย, ความเร็วเริ่มต้นสูง, ช่วงชีวิตสั้น
func create_sparks() -> GPUParticles2D:
var p = GPUParticles2D.new()
p.amount = 30
p.lifetime = 0.5
p.one_shot = true
p.explosiveness = 1.0 # All at once
var mat = ParticleProcessMaterial.new()
mat.direction = Vector3(0, -1, 0)
mat.spread = 180.0 # Full sphere
mat.initial_velocity_min = 150.0
mat.initial_velocity_max = 300.0
mat.gravity = Vector3(0, 200, 0) # Fall quickly
mat.damping_min = 10.0
mat.damping_max = 20.0
var grad = Gradient.new()
grad.colors = PackedColorArray([
Color(1, 1, 0.8, 1), Color(1, 0.7, 0.1, 1),
Color(1, 0.3, 0, 0.5), Color(0.5, 0.1, 0, 0)
])
grad.offsets = PackedFloat32Array([0.0, 0.2, 0.6, 1.0])
var grad_tex = GradientTexture1D.new()
grad_tex.gradient = grad
mat.color_ramp = grad_tex
# Scale: start small, stay small
mat.scale_min = 0.3
mat.scale_max = 0.6
p.process_material = mat
return p
หิมะ
พาร์ติเคิลสีขาว, ตกลงอย่างช้า ๆ นุ่มนวล, กระจายกว้าง, ลอยไปด้านข้างเล็กน้อย
func create_snow() -> GPUParticles2D:
var p = GPUParticles2D.new()
p.amount = 100
p.lifetime = 5.0
p.randomness = 0.8
var mat = ParticleProcessMaterial.new()
mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_BOX
mat.emission_box_extents = Vector3(500, 0, 0)
mat.direction = Vector3(0.1, 1, 0)
mat.spread = 10.0
mat.initial_velocity_min = 20.0
mat.initial_velocity_max = 40.0
mat.gravity = Vector3(0, 10, 0)
mat.damping_min = 1.0
mat.damping_max = 3.0
mat.angular_velocity_min = -45.0
mat.angular_velocity_max = 45.0
var grad = Gradient.new()
grad.colors = PackedColorArray([
Color(1, 1, 1, 0), Color(1, 1, 1, 0.8),
Color(1, 1, 1, 0.7), Color(1, 1, 1, 0)
])
grad.offsets = PackedFloat32Array([0.0, 0.05, 0.8, 1.0])
var grad_tex = GradientTexture1D.new()
grad_tex.gradient = grad
mat.color_ramp = grad_tex
mat.scale_min = 0.3
mat.scale_max = 0.8
p.process_material = mat
return p
8. พาร์ติเคิล 3D (GPUParticles3D)
GPUParticles3D ทำงานเหมือนกับ GPUParticles2D ทุกประการ แต่อยู่ในปริภูมิ 3D ใช้ ParticleProcessMaterial ตัวเดียวกัน ข้อแตกต่างหลัก:
- ทั้ง 3 แกนของ
Vector3ทำงาน (X, Y, Z) - รูปทรงการปล่อยทำงานในแบบ 3D เต็มรูปแบบ (ทรงกลมเป็นทรงกลมจริง, box เป็นปริมาตร)
- คุณสามารถใช้
draw_pass_1กับQuadMeshหรือ mesh ที่กำหนดเองสำหรับพาร์ติเคิลแบบ billboard - พาร์ติเคิลแบบ mesh สามารถใช้
StandardMaterial3DหรือORMMaterial3D
# 3D fire torch example var particles_3d = GPUParticles3D.new() particles_3d.amount = 60 particles_3d.lifetime = 1.0 var mat = ParticleProcessMaterial.new() mat.direction = Vector3(0, 1, 0) # Upward in 3D mat.spread = 20.0 mat.initial_velocity_min = 1.0 mat.initial_velocity_max = 2.0 mat.gravity = Vector3(0, -0.5, 0) # Slight counter-gravity # Emission from a small sphere mat.emission_shape = ParticleProcessMaterial.EMISSION_SHAPE_SPHERE mat.emission_sphere_radius = 0.2 particles_3d.process_material = mat # Use a QuadMesh as the particle shape var quad = QuadMesh.new() quad.size = Vector2(0.3, 0.3) particles_3d.draw_pass_1 = quad # Billboard mode: particles always face the camera mat.billboard_mode = BaseMaterial3D.BILLBOARD_ENABLED add_child(particles_3d)
.tres ที่กำหนดเองให้กับ draw_pass_1 และใช้ StandardMaterial3D กับมัน พาร์ติเคิลแต่ละตัวจะเรนเดอร์เป็นสำเนาของ mesh นั้น
9. Sub-Emitter
Godot 4 รองรับ sub-emitter สำหรับเอฟเฟกต์พาร์ติเคิลที่เกิดจากพาร์ติเคิลอีกที sub-emitter คือโหนด GPUParticles2D/GPUParticles3D อีกตัวที่ปล่อยพาร์ติเคิลที่ตำแหน่งของพาร์ติเคิลแม่แต่ละตัว เหมาะอย่างยิ่งสำหรับ:
- ประกายไฟที่กระเด็นออกจากพาร์ติเคิลไฟ
- รอยควันตามหลังการระเบิดของพลุ
- ละอองน้ำที่กระเซ็นเมื่อชน
- การระเบิดครั้งที่สอง
วิธีตั้งค่า sub-emitter:
# 1. Create the sub-emitter node (must be a sibling or child) var sub_sparks = GPUParticles2D.new() sub_sparks.amount = 4 sub_sparks.lifetime = 0.3 sub_sparks.explosiveness = 1.0 sub_sparks.emitting = false # Controlled by parent var sub_mat = ParticleProcessMaterial.new() sub_mat.direction = Vector3(0, -1, 0) sub_mat.spread = 180.0 sub_mat.initial_velocity_min = 50.0 sub_mat.initial_velocity_max = 100.0 sub_sparks.process_material = sub_mat add_child(sub_sparks) # 2. Reference it from the parent material var parent_mat: ParticleProcessMaterial = fire_particles.process_material parent_mat.sub_emitter_mode = ParticleProcessMaterial.SUB_EMITTER_AT_END # Also: SUB_EMITTER_AT_COLLISION, SUB_EMITTER_CONSTANT # 3. Set the sub_emitter property on the parent node fire_particles.sub_emitter = fire_particles.get_path_to(sub_sparks)
โหมด sub-emitter:
SUB_EMITTER_CONSTANT— ปล่อยอย่างต่อเนื่องจากพาร์ติเคิลแม่แต่ละตัวSUB_EMITTER_AT_END— ปล่อยเมื่อพาร์ติเคิลแม่หมดอายุSUB_EMITTER_AT_COLLISION— ปล่อยเมื่อพาร์ติเคิลแม่ชน
GPUParticles เท่านั้น ไม่ใช่ CPUParticles sub-emitter แต่ละตัวเพิ่มภาระให้ GPU ดังนั้นควรตั้งจำนวนพาร์ติเคิลของ sub-emitter ให้ต่ำ (4-8 ต่อพาร์ติเคิลแม่หนึ่งตัว)
10. เคล็ดลับด้านประสิทธิภาพ
-
การแลกเปลี่ยนระหว่าง Amount กับ Lifetime:
จำนวนพาร์ติเคิลที่มองเห็นทั้งหมด =
amountหากคุณเพิ่มlifetimeพาร์ติเคิลจะสะสมอยู่นานขึ้น ลดamountเพื่อชดเชย หรือเพิ่มขึ้นเพื่อให้เอฟเฟกต์หนาแน่นกว่า -
ใช้ Visibility Range (3D):
ตั้งค่า
visibility_range_endบน GPUParticles3D เพื่อให้ระบบพาร์ติเคิลที่อยู่ไกลหยุดเรนเดอร์ นี่เป็นประโยชน์อย่างมากสำหรับโลกแบบเปิด -
Fixed FPS:
ตั้งค่า
fixed_fpsบนโหนดพาร์ติเคิล (เช่น 30) เพื่อจำกัดการอัปเดตการจำลอง พาร์ติเคิลจะยังคงแทรกค่าอย่างราบรื่นแต่ใช้เวลา GPU น้อยลง -
One-shot สำหรับการพุ่งกระจาย:
สำหรับเอฟเฟกต์คล้ายการระเบิด ให้ใช้
one_shot = trueร่วมกับexplosiveness = 1.0จากนั้นสามารถปลดโหนดทิ้งได้หลังจากช่วงชีวิตสิ้นสุด -
ใช้ LOD สำหรับ 3D:
ผสม
visibility_range_begin/endกับโหนดพาร์ติเคิลหลายตัวที่ระดับรายละเอียดต่างกัน เพื่อสร้างเอฟเฟกต์พาร์ติเคิลแบบ LOD (Level of Detail) -
หลีกเลี่ยง overdraw:
พาร์ติเคิลกึ่งโปร่งใสจำนวนมากซ้อนทับกัน = fill rate ที่แพง ลด
amountแล้วใช้พาร์ติเคิลขนาดใหญ่ขึ้นที่มี alpha ต่ำลงแทน
11. การย้ายจาก Godot 3 ไป 4
หากคุณกำลังย้ายโปรเจกต์จาก Godot 3 ไป Godot 4 นี่คือการเปลี่ยนแปลงสำคัญสำหรับพาร์ติเคิล:
| Godot 3 | Godot 4 | หมายเหตุ |
|---|---|---|
Particles2D |
GPUParticles2D |
เปลี่ยนชื่อ |
Particles (3D) |
GPUParticles3D |
เปลี่ยนชื่อ |
ParticlesMaterial |
ParticleProcessMaterial |
เปลี่ยนชื่อพร้อมฟีเจอร์ใหม่ |
CPUParticles2D |
CPUParticles2D |
ไม่เปลี่ยนแปลง |
CPUParticles |
CPUParticles3D |
เปลี่ยนชื่อเพื่อความชัดเจน |
| ไม่มี sub-emitter | sub_emitter_mode |
ใหม่ใน Godot 4 |
| ไม่มี trail | trail_enabled |
ใหม่ใน Godot 4 |
flag_align_y |
particle_flag_align_y |
เปลี่ยนชื่อพรอเพอร์ตี |
ParticlesMaterial ใด ๆ ใน GDScript จะต้องอัปเดตด้วยตนเองเป็น ParticleProcessMaterial
ทำงานอัตโนมัติกับเอฟเฟกต์พาร์ติเคิลด้วย MCP Pro
อยากให้ AI สร้างเอฟเฟกต์พาร์ติเคิลให้คุณไหม? Godot MCP Pro มีเครื่องมือพาร์ติเคิลเฉพาะทางพร้อมพรีเซ็ตสำหรับไฟ, ควัน, ฝน, หิมะ, ประกายไฟ และอื่น ๆ ควบคุมมาเทเรียล, การไล่สี และรูปทรงการปล่อยได้เต็มที่จากการสนทนาเพียงครั้งเดียว
- create_particles
- set_particle_material
- set_particle_color_gradient
- apply_particle_preset
- get_particle_info