godot-performance-optimization

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Performance 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
    print()
    in release builds
    print()
    every frame = file I/O bottleneck + log spam. Use
    @warning_ignore
    or conditional
    if OS.is_debug_build():
    .
  • NEVER ignore
    VisibleOnScreenNotifier2D
    for off-screen entities
    — Enemies processing logic off-screen = wasted CPU. Disable
    set_process(false)
    when
    screen_exited
    .
  • NEVER instantiate nodes in hot loops
    for i in 1000: var bullet = Bullet.new()
    = 1000 allocations. Use object pools, reuse instances.
  • NEVER use
    get_node()
    in
    _process()
    — Calling
    get_node("Player")
    60x/sec = tree traversal spam. Cache in
    @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()
    —— 每帧调用
    print()
    会导致文件I/O瓶颈和日志泛滥。请使用
    @warning_ignore
    或条件判断
    if OS.is_debug_build():
    来控制。
  • 绝对不要忽略对屏幕外实体使用
    VisibleOnScreenNotifier2D
    —— 屏幕外的敌人仍在运行逻辑会浪费CPU资源。当触发
    screen_exited
    信号时,调用
    set_process(false)
    禁用其处理流程。
  • 绝对不要在热循环中实例化节点 ——
    for i in 1000: var bullet = Bullet.new()
    会产生1000次内存分配。请使用对象池,复用实例。
  • 绝对不要在
    _process()
    中调用
    get_node()
    —— 每秒调用60次
    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
undefined
gdscript
undefined

Add VisibleOnScreenNotifier2D

添加VisibleOnScreenNotifier2D

Disable processing when off-screen

当实体离开屏幕时禁用处理流程

func _on_screen_exited() -> void: set_process(false)
func _on_screen_entered() -> void: set_process(true)
undefined
func _on_screen_exited() -> void: set_process(false)
func _on_screen_entered() -> void: set_process(true)
undefined

Reduce Draw Calls

减少绘制调用

undefined
undefined

Use TextureAtlas (sprite sheets)

使用TextureAtlas(精灵图集)

Batch similar materials

批量处理相似材质

Fewer unique textures

减少唯一纹理的数量

undefined
undefined

Reference

参考资料

Related

相关内容

  • Master Skill: godot-master
  • 核心技能:godot-master",