Godot中子弹跟随玩家移动异常问题求助(附代码)
问题解决:Godot中子弹跟随玩家移动的修复
核心问题分析
- 子弹被设为玩家子节点:你在
shoot()函数中用add_child(Bullet)将子弹添加为玩家节点的子节点,子节点会自动继承父节点的位置变换,玩家移动时子弹会跟着偏移。 - 方向归一化未生效:
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
相关产品推荐
相关产品推荐

