HOME / 第 6 部分 · 数据与进阶开发 / 第 78 课
MODULE 6 · 数据与进阶开发
第 78 课 · 性能剖析与内存优化
🎯 本课学习目标
- 使用性能剖析工具
- 识别常见性能问题
- 掌握内存管理与优化技巧
游戏卡顿?内存爆涨?本课学会用 Godot 剖析工具定位并优化。
📖 详细教学步骤
剖析器(Profiler)工具
- 运行游戏(F5)
- 编辑器底部面板切到 调试器(Debugger)→ 剖析器(Profiler)
- 点「开始」记录,操作一会儿游戏,点「停止」
- 查看各函数的耗时占比(CPU 时间)
💡 耗时最多的函数就是优化重点。
常见性能问题排查排查
| 现象 | 可能原因 |
|---|---|
| 帧率低 | Draw Calls 多 / 特效重 / 脚本每帧重计算 |
| 内存涨 | 节点没释放 / 资源重复加载 / 泄漏 |
| 卡顿瞬间 | 同步加载 / GC / 物理大量碰撞 |
检查节点泄漏代码
运行时创建大量对象,若忘记释放会内存暴涨:
GDSCRIPTfunc spawn_bullet(pos: Vector2):
var b = bullet_scene.instantiate()
b.position = pos
add_child(b)
# 子弹一定要在生命周期结束时销毁!
# 例如子弹飞出屏幕或命中后:
# queue_free()
func check_memory():
print("当前节点数:", get_tree().get_node_count())
# 运行中数值持续增长 = 泄漏,要排查谁没释放
资源复用优化
避免重复加载:
GDSCRIPT# 错误: 每次调用都重新加载
func bad():
var tex = load("res://textures/bullet.png") # 重复加载
# 正确: 预加载一次,复用
const BULLET_TEX = preload("res://textures/bullet.png")
func good():
use(BULLET_TEX)
减少每帧计算优化
不必要的工作别每帧做:
GDSCRIPTfunc _process(delta):
# 错误: 每帧都创建临时数组
# var list = get_tree().get_nodes_in_group("enemy")
# 正确: 只在需要时更新(如每秒一次)
timer += delta
if timer >= 1.0:
timer = 0.0
refresh_enemy_list()
物理层优化优化
- 静态物体用 StaticBody,别用大量 RigidBody
- 关闭不需要的碰撞层检测
- 减少物理体数量(远处物体不参与物理)
- 碰撞形状尽量用简单形状
内存面板与调试工具
- 调试器 → 监视器(Monitors):看 Object Count、Nodes、内存
- 运行后回编辑器看「内存」标签
- Web 导出时留意内存峰值
⚠️
优化没效果?
先量化再优化:剖析器确认瓶颈在哪,改完再量对比。别盲改。
⚠️
内存一直涨?
用 get_node_count 和监视器定位泄漏;检查每帧 new/instantiate 的对象是否释放。
🧪 动手试一试
🏋️ 课后练习
用剖析器找出你上一个游戏里最耗时的函数,针对它做一次优化并对比前后 FPS。
Profiler 记录 → 排序耗时 → 优化热点 → 再测。
💡
「先测量、后优化」是铁律,性能优化最忌讳拍脑袋。
💡
把 FPS 显示在屏幕上(调试用),开发期随时观察。
🎓 本课小结
性能优化:剖析器定位热点 → 常见问题(Draw Calls/泄漏/同步加载)→ 节点释放检查、资源 preload 复用、减少每帧计算、物理层优化。