Godot 4.3中如何防止Slime敌人掉落平台?
问题根源与修复方案
核心问题
- 值传递导致修改无效:
check_down函数接收的veloc是Vector2值类型的副本,函数内修改它不会影响外部的velocity变量——这就是射线触发日志但角色仍掉落平台的关键原因。 - 语法笔误:函数内
veloc == Vector2.LEFT * moment_speed误用了比较运算符==,而非赋值运算符=,即使逻辑走到分支也不会修改速度。 - 速度未同步:函数内计算出的修正速度没有传递回角色的
velocity属性。
修复后的完整代码
extends CharacterBody2D const SPEED = 35 const SPEED_FOR_DETECTED = 45 var hp = 100 var player = null var player_chese = false var direction = Vector2.ZERO @onready var TimerForMoving = $TimerForMoving @onready var TimerForIdle = $TimerForIdle @onready var anim = $AnimatedSprite2D enum { IDLE, MOVING, DETECTED } var state = IDLE var Axis = [Vector2.LEFT, Vector2.RIGHT] func _physics_process(delta: float) -> void: # 添加重力 if not is_on_floor(): velocity += get_gravity() * delta if state == IDLE: if TimerForIdle.is_stopped(): velocity = Vector2.ZERO TimerForIdle.start(randi_range(1, 4)) elif state == MOVING: if TimerForMoving.is_stopped(): TimerForMoving.start(randi_range(1, 4)) velocity = Axis.pick_random() * SPEED elif state == DETECTED: TimerForIdle.stop() TimerForMoving.stop() var pos = (player.global_position - self.global_position).normalized() velocity = (Vector2.LEFT if Vector2.RIGHT.dot(pos) < Vector2.LEFT.dot(pos) else Vector2.RIGHT) * SPEED_FOR_DETECTED # 接收修正后的速度并赋值 velocity = check_down(velocity) move_and_slide() func check_down(veloc: Vector2) -> Vector2: var moment_speed = SPEED if state == IDLE else SPEED_FOR_DETECTED var dir = veloc.normalized() if dir == Vector2.LEFT and !$RayCast2DL.is_colliding(): print("left ray") return Vector2.RIGHT * moment_speed elif dir == Vector2.RIGHT and !$RayCast2DR.is_colliding(): print("Right ray") return Vector2.LEFT * moment_speed # 无修正需求时返回原速度 return veloc func _on_area_2d_entered_body_entered(body: Node2D) -> void: player = body player_chese = true state = DETECTED print("Enemy <Slime> detected Player;") func _on_timer_for_moving_timeout() -> void: state = IDLE func _on_timer_for_idle_timeout() -> void: state = MOVING func _on_area_2d_exit_body_exited(body: Node2D) -> void: player = null player_chese = false state = IDLE print("Enemy <Slime> can not detected Player.")
关键修改说明
- 调整
check_down为返回Vector2类型,将修正后的速度传递回外部的velocity变量 - 移除无效的赋值笔误,直接通过返回值完成速度修正
- 新增
dir变量存储归一化方向,避免重复计算 - 在
_physics_process中接收返回值并赋值,确保修正逻辑生效
内容的提问来源于stack exchange,提问作者miusGG
相关产品推荐
相关产品推荐

