16、粒子线条与视觉特效

第16章 粒子、线条与视觉特效

粒子系统结构示意图

复制代码
GPUParticles2D 节点结构:

  GPUParticles2D (节点)
  └── ParticleProcessMaterial (材质)
      ├── Direction: Vector3(0, -1, 0)  ← 发射方向(向上)
      ├── Spread: 45.0                  ← 扩散角度
      ├── Initial Velocity: 100~200     ← 初始速度范围
      ├── Gravity: Vector3(0, 200, 0)   ← 重力(向下拉)
      ├── Scale: 0.5~1.5                ← 大小范围
      └── Color Ramp: 黄→橙→红→透明     ← 颜色渐变

粒子生命周期:

  发射 → 飞行 → 减速 → 消失
   ●     ●     ●     ·
  (0s)  (0.3s) (0.7s) (1.0s)

常见粒子效果参数:

  爆炸:explosiveness=1.0, one_shot=true, spread=180°
  烟雾:gravity=-50(上浮), scale递增, alpha递减
  火花:velocity=300+, gravity=500, lifetime=0.3s
  拖尾:amount=20, spread=5°, 跟随物体

16.1 GPUParticles2D

gdscript 复制代码
extends GPUParticles2D

# 基本属性
amount = 50                # 粒子数量
lifetime = 1.0             # 粒子寿命
one_shot = false           # 是否一次性
explosiveness = 0.0        # 爆发性(0=均匀发射,1=同时发射)
emitting = true            # 是否发射

# Process Material 设置(在检查器中)
# Direction: 发射方向
# Spread: 扩散角度
# Gravity: 重力
# Initial Velocity: 初始速度
# Scale: 大小变化曲线
# Color: 颜色变化曲线

# 代码创建粒子材质
func setup_explosion_particles() -> void:
    var material := ParticleProcessMaterial.new()
    material.direction = Vector3(0, -1, 0)
    material.spread = 180.0
    material.initial_velocity_min = 100.0
    material.initial_velocity_max = 200.0
    material.gravity = Vector3(0, 200, 0)
    material.scale_min = 0.5
    material.scale_max = 1.5
    
    # 颜色渐变
    var gradient := Gradient.new()
    gradient.set_color(0, Color.YELLOW)
    gradient.set_color(0.5, Color.ORANGE)
    gradient.set_color(1, Color(1, 0, 0, 0))
    material.color_ramp = gradient
    
    process_material = material

# 爆炸效果
func explode() -> void:
    one_shot = true
    explosiveness = 1.0
    emitting = true
    await finished
    queue_free()

16.2 Line2D 拖尾效果

gdscript 复制代码
extends Line2D

@export var max_points: int = 20
@export var target: Node2D

# 预创建 Gradient(避免每帧创建新对象)
var trail_gradient: Gradient

func _ready() -> void:
    trail_gradient = Gradient.new()
    width_curve = null  # 使用默认宽度

func _process(delta: float) -> void:
    if target:
        add_point(target.global_position)
        
        # 限制点数
        while get_point_count() > max_points:
            remove_point(0)
    
    # 更新渐变透明度(只在点数变化时更新)
    var point_count := get_point_count()
    if point_count > 1:
        # 重新设置渐变点数
        trail_gradient.set_point_count(point_count)
        for i in point_count:
            var alpha := float(i) / (point_count - 1)
            trail_gradient.set_color(i, Color(1, 1, 1, alpha))
            trail_gradient.set_offset(i, float(i) / (point_count - 1))
        gradient = trail_gradient

16.3 MultiMeshInstance2D(大量精灵)

gdscript 复制代码
# 当需要渲染数百/数千个相同精灵时使用
# 例如:弹幕、草丛、装饰物

extends MultiMeshInstance2D

@export var count: int = 1000
@export var area_size: Vector2 = Vector2(1000, 1000)

func _ready() -> void:
    var mm := MultiMesh.new()
    mm.instance_count = count
    mm.transform_format = MultiMesh.TRANSFORM_2D
    
    # 设置纹理
    texture = preload("res://assets/sprites/grass.png")
    
    # 随机放置
    for i in count:
        var s := randf_range(0.8, 1.2)
        var xform := Transform2D(
            0,                                    # 旋转角度
            Vector2(s, s),                        # 缩放
            0,                                    # 倾斜
            Vector2(                              # 位置
                randf() * area_size.x,
                randf() * area_size.y
            )
        )
        mm.set_instance_transform_2d(i, xform)
    
    multimesh = mm

16.4 Tween 动画

gdscript 复制代码
# 基本 Tween
func move_to(target_pos: Vector2, duration: float) -> void:
    var tween := create_tween()
    tween.tween_property(self, "position", target_pos, duration)

# 并行动画
func complex_animation() -> void:
    var tween := create_tween().set_parallel(true)
    tween.tween_property(self, "position", Vector2(200, 200), 0.5)
    tween.tween_property(self, "rotation", TAU, 0.5)
    tween.tween_property(self, "modulate:a", 0.0, 0.5)

# 链式动画(顺序执行)
func chain_animation() -> void:
    var tween := create_tween()
    tween.tween_property(self, "position:x", 200, 0.3)
    tween.tween_property(self, "position:y", 200, 0.3)
    tween.tween_property(self, "modulate:a", 0.0, 0.2)
    tween.tween_callback(queue_free)

# 循环动画
func pulse_animation() -> void:
    var tween := create_tween().set_loops()
    tween.tween_property(self, "scale", Vector2(1.2, 1.2), 0.5)
    tween.tween_property(self, "scale", Vector2.ONE, 0.5)

# 等待信号(4.7 新增)
func wait_for_animation() -> void:
    var tween := create_tween()
    tween.tween_property(self, "position:x", 200, 1.0)
    tween.tween_await(some_signal)  # 等待信号后再继续
    tween.tween_property(self, "position:x", 0, 1.0)

# 检查 Tween 是否还有动画(4.7 新增)
func _process(delta: float) -> void:
    if tween and tween.is_valid() and tween.has_tweeners():
        print("动画还在播放")

16.5 自定义绘制(_draw)

gdscript 复制代码
extends Node2D

@export var circle_radius: float = 50.0
@export var line_color: Color = Color.RED

func _draw() -> void:
    # 绘制圆形
    draw_circle(Vector2.ZERO, circle_radius, line_color)
    
    # 绘制线段
    draw_line(Vector2(-100, 0), Vector2(100, 0), Color.GREEN, 2.0)
    
    # 绘制矩形
    draw_rect(Rect2(-50, -50, 100, 100), Color.BLUE, false, 2.0)
    
    # 绘制弧线
    draw_arc(Vector2.ZERO, 80, 0, PI, 32, Color.YELLOW, 2.0)

# 属性改变时重绘
@export var radius: float = 50.0:
    set(value):
        radius = value
        queue_redraw()  # 触发重绘
相关推荐
心前阳光12 小时前
Unity发布PC软件图标不能改变
unity·游戏引擎
an869500120 小时前
unity如何在visual studio中打断点debug
unity·游戏引擎·visual studio
xcLeigh21 小时前
Unity基础:使用Transform控制物体移动——Translate与position详解
unity·游戏引擎
FairGuard手游加固1 天前
Unity小游戏加密:global-metadata.dat与AssetBundle保护
游戏·unity·游戏引擎
狂人开飞机1 天前
11、UI系统
游戏引擎·godot
真鬼1231 天前
【Unity AI】Untiy链接cursor与MCP
unity·游戏引擎
郝学胜-神的一滴1 天前
C++11 工程级应用 10:减少拷贝,让容器跑得更快
服务器·开发语言·c++·游戏引擎·opengl
玖玥拾1 天前
Lua 基础语法(八) Unity Huatuo (HybridCLR)
开发语言·unity·游戏引擎·lua
狂人开飞机1 天前
10、相机系统
游戏引擎·godot