HOME / 第 6 部分 · 数据与进阶开发 / 第 75 课
MODULE 6 · 数据与进阶开发

第 75 课 · 2D 光照与发光

⏱ 预计时长 35 分钟📊 难度 进阶📚 模块 第 6 部分 · 数据与进阶开发

🎯 本课学习目标

2D 游戏也能有光照!火把、手电、昼夜循环让画面瞬间高级。本课实现 2D 光照。

📖 详细教学步骤

开启 2D 光照搭建

2D 光照三要素:

  1. CanvasModulate:控制全局亮度(夜晚调暗)
  2. PointLight2D:点光源(火光、灯光)
  3. Light2D 的阴影:需要配合光遮蔽(Occluder2D)

设置环境与点光源实操

  1. 场景加 CanvasModulate:Color 调暗(如 (0.1, 0.1, 0.25) = 夜晚)
  2. PointLight2D,设置 Texture(光斑图)、Energy(强度)、Color
  3. 在玩家身上加一个 PointLight2D(火把效果)

💡 光斑图决定光照形状:圆形光斑最常用。

光遮蔽阴影实操

让光照不到墙后面:

  1. 给墙壁加子节点 LightOccluder2D
  2. Occluder → 新建 OccluderPolygon2D,沿墙边画多边形
  3. 灯光照到墙时产生阴影

💡 也可以自动生成:选中墙的碰撞形状 → 生成遮挡。

手电筒(聚光)进阶

PointLight2D 的 Texture 换成「锥形光」图,再让灯跟随鼠标方向:

GDSCRIPTextends Node2D

@onready var flashlight: PointLight2D = $Flashlight

func _process(delta):
    # 让手电朝鼠标方向旋转
    var mouse = get_global_mouse_position()
    flashlight.rotation = (mouse - global_position).angle()

昼夜循环代码

CanvasModulate 颜色随时间变化模拟昼夜:

GDSCRIPTextends CanvasModulate

@export var cycle_speed: float = 0.02

func _process(delta):
    # 用正弦让亮度循环
    var t = Time.get_ticks_msec() / 1000.0 * cycle_speed
    var brightness = 0.5 + 0.5 * sin(t)
    # 亮时白昼、暗时深蓝夜
    color = Color(0.15 + 0.85 * brightness,
                  0.2 + 0.8 * brightness,
                  0.5 + 0.5 * brightness)

光与氛围搭配实操

  • 火把:暖黄光(Orange)+ 轻微闪烁(随机 Energy)
  • 月光:冷蓝光 + 低能量
  • 夜晚暗角:CanvasModulate 暗 + 手电照亮
  • 火焰光闪烁:
GDSCRIPTfunc _process(delta):
    # 火焰光轻微闪烁
    $Torch.energy = 1.0 + sin(Time.get_ticks_msec() * 0.02) * 0.15
⚠️
光照没效果?

确认:①CanvasModulate 调暗了;②PointLight2D 有 Texture;③场景用了 2D 渲染且光照启用。

⚠️
阴影不出现?

需要 LightOccluder2D 遮挡物。另外光源要勾选 Shadow Enabled(检查器阴影选项)。

🧪 动手试一试

🏋️ 课后练习

做一个夜晚场景:全局暗,玩家举着火把(暖黄光 + 闪烁),墙壁遮挡光线产生阴影,再加一个月光。

CanvasModulate + 两个 PointLight2D + LightOccluder2D。

💡

2D 光照是氛围神器,配合粒子(火光)效果翻倍。

💡

光照性能开销可控,移动端也常见。

🎓 本课小结

2D 光照:CanvasModulate 调全局亮度 + PointLight2D 点光源 + LightOccluder2D 阴影遮蔽;可做手电、火把、昼夜循环。