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

Godot中子弹跟随玩家移动异常问题求助(附代码)

问题解决:Godot中子弹跟随玩家移动的修复

核心问题分析

  1. 子弹被设为玩家子节点:你在shoot()函数中用add_child(Bullet)将子弹添加为玩家节点的子节点,子节点会自动继承父节点的位置变换,玩家移动时子弹会跟着偏移。
  2. 方向归一化未生效:bullet_direction.normalized()是返回新的归一化向量,不会修改原变量,导致方向向量可能未正确归一化,影响子弹飞行轨迹。

修复步骤及代码修改

1. 调整子弹的父节点

将子弹添加到场景树根节点(或专门的子弹管理容器),避免继承玩家的位置变换:
修改玩家代码中的shoot()函数:

func shoot():
    var Bullet = bullet_scene.instance()
    # 改为添加到场景树根节点,而非玩家子节点
    get_tree().root.add_child(Bullet)
    Bullet.global_position = global_position
    Bullet.direction = bullet_direction

2. 修复方向归一化

将bullet_direction.normalized()改为赋值语句,确保方向向量被正确归一化:
修改玩家代码中射击部分的方向处理:

bullet_direction = Vector2(
    Input.get_action_strength("right") - Input.get_action_strength("left"),
    Input.get_action_strength("down") - Input.get_action_strength("up")
)
# 修复:将归一化后的向量赋值给原变量
if bullet_direction != Vector2.ZERO:
    bullet_direction = bullet_direction.normalized()
    shoot()

完整修改后的玩家代码

extends KinematicBody2D
export var speed := 75
var _velocity := Vector2.ZERO
export (PackedScene) var bullet_scene
var bullet_direction = Vector2(0, 0)

func _physics_process(_delta: float) -> void:
    # 移动逻辑
    var direction := Vector2(
        Input.get_action_strength("move_right") - Input.get_action_strength("move_left"),
        Input.get_action_strength("move_down") - Input.get_action_strength("move_up")
    )
    if direction.length() > 1.0:
        direction = direction.normalized()
    _velocity = move_and_slide(speed * direction)
    
    # 动画切换逻辑
    if direction.x >= 0.1:
        $AnimatedSprite.animation = "Right"
    elif direction.x <= -0.1:
        $AnimatedSprite.animation = "Left"
    elif direction.y >= 0.1:
        $AnimatedSprite.animation = "Down"
    elif direction.y <= -0.1:
        $AnimatedSprite.animation = "Up"
    else:
        $AnimatedSprite.animation = "Idle"
    
    # 射击逻辑
    bullet_direction = Vector2(
        Input.get_action_strength("right") - Input.get_action_strength("left"),
        Input.get_action_strength("down") - Input.get_action_strength("up")
    )
    if bullet_direction != Vector2.ZERO:
        bullet_direction = bullet_direction.normalized()
        shoot()

func shoot():
    var Bullet = bullet_scene.instance()
    get_tree().root.add_child(Bullet)
    Bullet.global_position = global_position
    Bullet.direction = bullet_direction

子弹代码无需修改(若Timer节点已正确连接信号)

确保子弹场景中的Timer节点已连接timeout信号到_on_Timer_timeout()函数,用于自动销毁子弹。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 07:48:45