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)
  • explosiveness0.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
เคล็ดลับ: จบการไล่สีด้วย alpha = 0 เสมอ เพื่อให้พาร์ติเคิลค่อย ๆ เฟดออกอย่างราบรื่นแทนที่จะหายวับไปทันที

คุณยังตั้งค่าพรอเพอร์ตี 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)
เคล็ดลับ: สำหรับพาร์ติเคิลแบบ mesh (เศษซาก, ปลอกกระสุน, ก้อนต่าง ๆ) ให้กำหนด mesh .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ปล่อยเมื่อพาร์ติเคิลแม่ชน
คำเตือน: sub-emitter ทำงานกับ 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 เปลี่ยนชื่อพรอเพอร์ตี
เคล็ดลับ: ตัวแปลงโปรเจกต์ของ Godot จัดการการเปลี่ยนชื่อส่วนใหญ่โดยอัตโนมัติ อย่างไรก็ตาม การอ้างอิง ParticlesMaterial ใด ๆ ใน GDScript จะต้องอัปเดตด้วยตนเองเป็น ParticleProcessMaterial

ทำงานอัตโนมัติกับเอฟเฟกต์พาร์ติเคิลด้วย MCP Pro

อยากให้ AI สร้างเอฟเฟกต์พาร์ติเคิลให้คุณไหม? Godot MCP Pro มีเครื่องมือพาร์ติเคิลเฉพาะทางพร้อมพรีเซ็ตสำหรับไฟ, ควัน, ฝน, หิมะ, ประกายไฟ และอื่น ๆ ควบคุมมาเทเรียล, การไล่สี และรูปทรงการปล่อยได้เต็มที่จากการสนทนาเพียงครั้งเดียว

  • create_particles
  • set_particle_material
  • set_particle_color_gradient
  • apply_particle_preset
  • get_particle_info
รับ MCP Pro — $15