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

Godot 4.2.2:2D玩家角色无法识别地面接触问题求助

排查Godot 4.2.2中CharacterBody2D的is_on_floor()检测失效问题

你遇到的is_on_floor()始终返回false的问题,核心是代码违反了CharacterBody2D的物理移动规范,加上语法和逻辑错误导致的,具体问题和修复方案如下:

原代码问题分析

extends CharacterBody2D

var dash = 300.0
var speed = 150.0
var jumpPower = -350.0
var jumpMax = 2
var jumpCount = 0

func _process(delta):
 moviment(delta)
 attack()
 print(is_on_floor())
 move_and_slide()

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
func _physics_process(delta):

 move_and_collide(Vector2(0, 1))
 velocity.y += gravity * delta
 var motion = velocity * delta
 move_and_collide(motion)
func moviment(delta)
    var direction = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
if direction != 0:

    $Anim.play("Walk")
    if direction > 0:
        $Anim.flip_h = false
        velocity.x += speed * delta
        velocity.x = clamp(speed, 100.0, speed)
    elif direction < 0:
        $Anim.flip_h = true
        velocity.x -= speed * delta
        velocity.x = clamp(-speed, 100.0, -speed)
else:

    velocity.x = 0
    $Anim.play("Idle")
jump()

func jump():

if is_on_floor() and jumpCount != 0:
    jumpCount = 0
if jumpCount<jumpMax:
    if Input.is_action_just_pressed("move_up"):
        jumpCount += 1
        $Anim.play("Jump")
        velocity.y = jumpPower

关键问题点

  • 物理与帧逻辑混用:CharacterBody2D的移动、物理相关逻辑必须放在_physics_process中,你在_process(帧更新)里调用move_and_slide,同时在_physics_process里调用move_and_collide,两种移动方法混用会彻底打乱物理状态,is_on_floor()完全依赖move_and_slide的碰撞结果,这样调用根本无法正确检测地面。
  • 错误使用move_and_collide:CharacterBody2D的标准移动方式是修改velocity后调用move_and_slide(),move_and_collide不会更新is_on_floor()所需的碰撞状态。
  • 语法与缩进错误:moviment(delta)函数定义缺少冒号,多处代码缩进错误(比如if direction !=0:的代码块未正确缩进),导致逻辑执行顺序混乱。
  • 速度计算逻辑错误:clamp(speed, 100.0, speed)写法无效,clamp参数顺序为clamp(值, 最小值, 最大值),应该直接用方向乘以速度控制水平移动。

修复后的代码

extends CharacterBody2D

var dash = 300.0
var speed = 150.0
var jumpPower = -350.0
var jumpMax = 2
var jumpCount = 0
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(delta):
    # 处理重力
    velocity.y += gravity * delta
    # 处理移动和跳跃
    moviment(delta)
    jump()
    # 执行移动,这一步会更新is_on_floor的状态
    move_and_slide()
    # 打印检测结果
    print(is_on_floor())

func moviment(delta):
    var direction = Input.get_action_strength("move_right") - Input.get_action_strength("move_left")
    if direction != 0:
        $Anim.play("Walk")
        # 直接用方向乘以速度设置水平速度
        velocity.x = direction * speed
        $Anim.flip_h = direction < 0
    else:
        velocity.x = 0
        $Anim.play("Idle")

func jump():
    # 接触地面时重置跳跃次数
    if is_on_floor():
        jumpCount = 0
    # 处理跳跃输入
    if jumpCount < jumpMax and Input.is_action_just_pressed("move_up"):
        jumpCount += 1
        $Anim.play("Jump")
        velocity.y = jumpPower

额外注意事项

  • 确保角色和地面都添加了CollisionShape2D或CollisionPolygon2D,且碰撞层与掩码设置正确(角色和地面的碰撞层需能互相检测)。
  • jumpPower设为负数是正确的(Godot 2D中y轴向下为正),若场景坐标系有修改,需对应调整。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 05:48:28