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

如何实现游戏中敌人沿X、Y轴坐标追踪玩家?

敌人Y轴追踪失效问题解决方法

问题描述

开发游戏敌人追踪玩家功能时,玩家可沿X、Y轴移动,敌人X轴追踪正常,但Y轴无法向玩家位置移动,当前使用的GDScript代码如下:

var _can_attack = false
var _collision_weapon_default_positionX:float
var _raycast_default_rotate_position:float
var _player_ref:Player
var _enemy_direction:Vector2 = Vector2.ZERO 
var target_position

func _physics_process(delta: float) -> void:
    enemy_attack()  
    _flip_me()
    _enemy_move()   
    
func _enemy_move() -> void:
    var x_direction = sign(_player_ref.global_position.x - global_position.x)
    var y_direction = sign(_player_ref.global_position.y - global_position.y)
    _enemy_direction = Vector2(x_direction, y_direction).normalized() * speed
    velocity = _enemy_direction
    move_and_slide()
        
func _flip_me() -> void:
    if(_player_ref.global_position.x > global_position.x):
        animated_sprite.flip_h = false
        collision_shape_2d_attack.position.x = _collision_weapon_default_positionX
        ray_cast_2d.rotation = _raycast_default_rotate_position
    elif(_player_ref.global_position.x < global_position.x):
        animated_sprite.flip_h = true
        collision_shape_2d_attack.position.x = -_collision_weapon_default_positionX
        ray_cast_2d.rotation = -_raycast_default_rotate_position

问题原因

  1. move_and_slide默认重力干扰:move_and_slide方法默认以Vector2.UP为向上方向,自动对Y轴速度应用重力,导致你设置的Y轴追踪速度被抵消。
  2. 方向计算逻辑缺陷:用sign()获取X/Y方向后再归一化,当敌人与玩家Y坐标差值极小时,sign()会返回0,直接丢失Y轴方向;同时这种方式只能生成8个固定方向的移动向量,平滑度差且易出现Y轴无动力的情况。

解决方法

方法1:修正move_and_slide调用,消除重力影响

调用move_and_slide时明确传入第二个参数为Vector2.ZERO,关闭自动重力处理:

func _enemy_move() -> void:
    var x_direction = sign(_player_ref.global_position.x - global_position.x)
    var y_direction = sign(_player_ref.global_position.y - global_position.y)
    _enemy_direction = Vector2(x_direction, y_direction).normalized() * speed
    velocity = _enemy_direction
    move_and_slide(velocity, Vector2.ZERO)  # 关闭默认重力影响

方法2:优化方向计算逻辑(推荐)

直接通过玩家与敌人的位置差向量计算移动方向,避免sign()带来的问题,同时让移动更平滑:

func _enemy_move() -> void:
    # 计算玩家与敌人的位置差向量
    var direction = _player_ref.global_position - global_position
    # 避免距离过近时出现计算异常,仅当距离大于阈值时归一化
    if direction.length() > 1:
        direction = direction.normalized()
    _enemy_direction = direction * speed
    velocity = _enemy_direction
    move_and_slide(velocity, Vector2.ZERO)

额外检查点

  • 确认敌人节点(如KinematicBody2D)没有在其他代码中单独赋值velocity.y(比如重力相关代码),避免覆盖追踪的Y轴速度。
  • 检查speed变量是否已正确赋值,确保不为0。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 10:47:03