Hydro
Hydro

Reputation: 281

Child node (Bullet) follows Parent node (Revolver) in Godot

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

Answers (1)

Theraot
Theraot

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:

  • The parent: 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).
  • The owner: 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).
  • The root: 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

Related Questions