You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot中_process()与_physics_process()的正确使用场景及示例问询

Godot中_process()与_physics_process()的正确使用场景与输入处理问题解析

核心差异梳理

  • _process(delta):每帧调用一次,调用频率随设备帧率波动(帧率掉帧时间隔变长,卡顿严重时可能暂停调用)。delta是上一帧到当前帧的时间差,适合处理非物理相关的视觉/UI逻辑,比如UI动画、相机平滑跟随、粒子效果更新等。
  • _physics_process(delta):以固定频率调用(默认60次/秒,可在项目设置Physics -> Common -> Physics Tick Rate修改),不受帧率影响。这里的delta是固定物理步长,专门用于处理物理相关逻辑,比如刚体运动、碰撞检测、角色移动(尤其是KinematicBody/RigidBody相关操作)。

为什么Godot推荐在_physics_process()中处理输入?

你遇到的两个问题本质是输入与物理逻辑不同步导致的:

  1. 启动时输入无响应:Godot启动初期,_process()会先于物理系统初始化完成前调用几次,此时输入事件队列未完全同步,按键操作无法被正确捕获。
  2. 卡顿场景下输入丢失:帧率暴跌时_process()会停止调用,但物理系统仍按固定频率运行。若输入逻辑放在_process(),这段时间的按键会被完全忽略;而物理帧继续执行旧的运动状态,就会出现“输入没反应但角色还在移动”的脱节情况。

另外,角色移动(比如KinematicBody的move_and_slide)属于物理操作,必须在_physics_process()中执行,否则会出现碰撞检测失效、移动卡顿/跳帧的问题——物理引擎仅在物理帧更新时处理碰撞与运动状态。

正确的3D角色移动实现示例

以下是适配Godot最佳实践的3D角色移动脚本,需挂载到KinematicBody节点(需搭配Mesh和球形CollisionShape):

extends KinematicBody

export var move_speed: float = 5.0
export var gravity: float = 9.8
export var jump_force: float = 4.0

var velocity: Vector3 = Vector3.ZERO

func _physics_process(delta: float) -> void:
    # 在物理帧读取输入,保证输入不丢失
    var input_dir: Vector3 = Vector3.ZERO
    if Input.is_action_pressed("ui_left"):
        input_dir.x -= 1
    if Input.is_action_pressed("ui_right"):
        input_dir.x += 1
    if Input.is_action_pressed("ui_forward"):
        input_dir.z -= 1
    if Input.is_action_pressed("ui_backward"):
        input_dir.z += 1
    
    # 归一化输入方向,避免斜向移动速度过快
    if input_dir.length() > 0:
        input_dir = input_dir.normalized()
        # 将输入方向转换为世界空间(基于角色自身朝向)
        input_dir = get_global_transform().basis.xform(input_dir)
        velocity.x = input_dir.x * move_speed
        velocity.z = input_dir.z * move_speed
    else:
        # 无输入时平滑减速
        velocity.x = move_toward(velocity.x, 0, move_speed * delta * 5)
        velocity.z = move_toward(velocity.z, 0, move_speed * delta * 5)
    
    # 处理重力与跳跃
    if is_on_floor():
        velocity.y = 0
        if Input.is_action_just_pressed("ui_jump"):
            velocity.y = jump_force
    else:
        velocity.y -= gravity * delta
    
    # 执行物理移动(必须在_physics_process中调用)
    velocity = move_and_slide(velocity, Vector3.UP)

总结

  • 用_process()处理非物理相关的视觉/UI逻辑:比如UI动画、相机平滑、粒子效果更新等。
  • 用_physics_process()处理所有物理相关逻辑:包括输入读取(尤其是和角色移动、物理交互相关的输入)、刚体运动、碰撞检测、KinematicBody移动等。

内容的提问来源于stack exchange,提问作者Olivier Pons

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 19:54:27