Reputation: 281
I have checked my code with other code that I have written before to shoot bullets where it worked. I began getting problems with Godot a month ago with similar things and I do not know why. Anyways, I am trying to make a player who walks with WASD and can shoot with the arrow keys. Shooting works, although that also had some strange problems although the same code works in other projects. Anyways, I can shoot but the bullets follow the player, which shouldn't happen since, as already stated, it doesn't happen in other projects and in YouTube tutorials. The player code is:
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:
#move
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"
#shooting
bullet_direction = Vector2(
Input.get_action_strength("right") - Input.get_action_strength("left"),
Input.get_action_strength("down") - Input.get_action_strength("up")
)
bullet_direction.normalized()
if bullet_direction != Vector2.ZERO:
shoot()
func shoot():
var Bullet = bullet_scene.instance()
add_child(Bullet)
Bullet.global_position = global_position
Bullet.direction = bullet_direction
The script for the bullet is really simple:
extends Area2D
var speed = 300
var direction = Vector2(0, 0)
func _physics_process(delta):
position += direction * speed * delta
func _on_Timer_timeout():
queue_free()
Also, I had a weapon node (Just a Node2D) which I added as a Child to the Player Scene but it had the same problem. The code for that was the exact same code as the one in the Player Script which handles the shooting. I have tried to solve this problem for a long time now and couldn't find the answer so I would appreciate an answer. :D
Upvotes: 1
Views: 2376
Reputation: 40295
Children nodes move with the parent by default. This is normal behavior.
You can disable that behavior by calling set_as_toplevel
:
var Bullet = bullet_scene.instance()
add_child(Bullet)
Bullet.set_as_toplevel(true)
For completeness I'll also mention that another solution is to not make the bullet a child of the kinematic body, but of something else that won't move (For example to avoid removing the bullets when removing the kinematic body). Your initially available options are:
get_parent().add_child(Bullet)
. This adds the bullet to whatever node is the parent of the kinematic body. Parent would be null only if the kinematic body is the root of the scene tree… Which should not happen (the root of the scene tree is a Viewport
).owner.add_child(Bullet)
. This adds the bullet to the root of the scene where the kinematic body is added. But the owner might not be set, in particular if the kinematic body was added from code instead of the editor (in which case you would have to set the owner from code too).get_tree().root.add_child(Bullet)
. This adds the bullet to the root of the scene tree (that Viewport
I was talking about). It is never null, but it might not be where you want the bullets.Otherwise have some defined container for the bullets that you can reference.
Upvotes: 2