godot-performance-optimization
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChinesePerformance Optimization
性能优化
Profiler-driven analysis, object pooling, and visibility culling define optimized game performance.
基于Profiler的分析、对象池和可见性剔除是实现游戏性能优化的核心方法。
Available Scripts
可用脚本
custom_performance_monitor.gd
custom_performance_monitor.gd
Manager for adding and updating custom performance monitors in the Godot debugger.
用于在Godot调试器中添加和更新自定义性能监视器的管理脚本。
multimesh_foliage_manager.gd
multimesh_foliage_manager.gd
Expert MultiMesh pattern for rendering thousands of foliage instances efficiently.
使用MultiMesh模式高效渲染数千个植被实例的实现方案。
NEVER Do in Performance Optimization
性能优化的禁忌
- NEVER optimize without profiling first — "I think physics is slow" without data? Premature optimization. ALWAYS use Debug → Profiler (F3) to identify actual bottleneck.
- NEVER use in release builds —
print()every frame = file I/O bottleneck + log spam. Useprint()or conditional@warning_ignore.if OS.is_debug_build(): - NEVER ignore for off-screen entities — Enemies processing logic off-screen = wasted CPU. Disable
VisibleOnScreenNotifier2Dwhenset_process(false).screen_exited - NEVER instantiate nodes in hot loops — = 1000 allocations. Use object pools, reuse instances.
for i in 1000: var bullet = Bullet.new() - NEVER use in
get_node()— Calling_process()60x/sec = tree traversal spam. Cache inget_node("Player").@onready var player := $Player - NEVER forget to batch draw calls — 1000 unique sprites = 1000 draw calls. Use TextureAtlas (sprite sheets) + MultiMesh for instanced rendering.
Debug → Profiler (F3)
Tabs:
- Time: Function call times
- Memory: RAM usage
- Network: RPCs, bandwidth
- Physics: Collision checks
- 绝对不要在未分析前就优化 —— 没有数据支撑就说“我觉得物理模块很慢”属于过早优化。务必使用Debug → Profiler(F3)来定位实际的性能瓶颈。
- 绝对不要在发布版本中使用—— 每帧调用
print()会导致文件I/O瓶颈和日志泛滥。请使用print()或条件判断@warning_ignore来控制。if OS.is_debug_build(): - 绝对不要忽略对屏幕外实体使用—— 屏幕外的敌人仍在运行逻辑会浪费CPU资源。当触发
VisibleOnScreenNotifier2D信号时,调用screen_exited禁用其处理流程。set_process(false) - 绝对不要在热循环中实例化节点 —— 会产生1000次内存分配。请使用对象池,复用实例。
for i in 1000: var bullet = Bullet.new() - 绝对不要在中调用
_process()—— 每秒调用60次get_node()会频繁遍历节点树。请在get_node("Player")中缓存节点引用。@onready var player := $Player - 绝对不要忘记批量处理绘制调用 —— 1000个独立精灵会产生1000次绘制调用。请使用TextureAtlas(精灵图集)+ MultiMesh进行实例化渲染。
Debug → Profiler(F3)
标签页:
- Time:函数调用耗时
- Memory:内存使用情况
- Network:RPC调用、带宽占用
- Physics:碰撞检测情况
Common Optimizations
常见优化方案
Object Pooling
对象池
gdscript
var bullet_pool: Array[Node] = []
func get_bullet() -> Node:
if bullet_pool.is_empty():
return Bullet.new()
return bullet_pool.pop_back()
func return_bullet(bullet: Node) -> void:
bullet.hide()
bullet_pool.append(bullet)gdscript
var bullet_pool: Array[Node] = []
func get_bullet() -> Node:
if bullet_pool.is_empty():
return Bullet.new()
return bullet_pool.pop_back()
func return_bullet(bullet: Node) -> void:
bullet.hide()
bullet_pool.append(bullet)Visibility Notifier
可见性通知器
gdscript
undefinedgdscript
undefinedAdd VisibleOnScreenNotifier2D
添加VisibleOnScreenNotifier2D
Disable processing when off-screen
当实体离开屏幕时禁用处理流程
func _on_screen_exited() -> void:
set_process(false)
func _on_screen_entered() -> void:
set_process(true)
undefinedfunc _on_screen_exited() -> void:
set_process(false)
func _on_screen_entered() -> void:
set_process(true)
undefinedReduce Draw Calls
减少绘制调用
undefinedundefinedUse TextureAtlas (sprite sheets)
使用TextureAtlas(精灵图集)
Batch similar materials
批量处理相似材质
Fewer unique textures
减少唯一纹理的数量
undefinedundefinedReference
参考资料
Related
相关内容
- Master Skill: godot-master
- 核心技能:godot-master",