godotgodot3

How do I properly shoot from the player position in Godot 3.5?


I am making a 2d runner game in Godot 3.5 and shooting is a component of it enter image description here

Everything works fine, but there is a technical problem with the bullet positioning. I am relatively new to coding in general too, so best believe I've tried all ways of dealing with it.

When I click tab button, the bullets stack up on top as shown. I want it to shoot from the player's position. I don't know how to fix this. Any suggestions would be appreciated.

enter image description here

enter image description here

Player: enter image description here




const UP = Vector2(0, -1)
const SPEED = 200
const GRAVITY = 20
const JUMP_HEIGHT = -690
var motion = Vector2() # moving in 2d space

func _physics_process(_delta):
    motion.y += GRAVITY

    if Input.is_action_pressed("ui_right"):
        $Sprite.flip_h = false # Do not flip the sprite
        motion.x = SPEED
    elif Input.is_action_pressed("ui_left"):
        $Sprite.flip_h = true # Flip the sprite to face left
        motion.x = -SPEED
    else:
        motion.x = 0

    # Play appropriate animation based on character's movement
    if motion.x != 0: # If character is moving
        $Sprite.play("Run")
    else:
        $Sprite.play("Idle") # Match the play actions to the names of the animation states

    if is_on_floor():
        if Input.is_action_pressed("ui_up"):
            motion.y = JUMP_HEIGHT
    else:
        if motion.y < 0:
            $Sprite.play("Jump")
            print("jump")
        else:
            $Sprite.play("Fall")
            print("fall")

    # use move_and_slide to create movement on screen
    motion = move_and_slide(motion, UP)


# bullets

const SHOOT_SPEED = 300
var bulletscene = preload("res://Shoot.tscn")

func _process(delta):
    if Input.is_action_just_pressed("ui_accept"):
        shoot()

    $Node2D.look_at(get_global_mouse_position())

func shoot():
    var bullet = bulletscene.instance()

    get_parent().add_child(bullet)
    bullet.position = $Node2D/Position2D.position

    bullet.velocity = get_global_mouse_position() - bullet.position

Solution

  • First, as I see in your image, the Shoot scene has their Sprite2D and CollisionShape2D all over the place. This could results in strange graphical bugs. You should make sure that their transform positions and offset is set to 0 both axes in their local scene.

    Second, the position property is for relative position in their local scene. You should use global_position to copy the player's Position2D.

    func shoot():
        var bullet = bulletscene.instance()
    
        get_parent().add_child(bullet)
        bullet.global_position = $Node2D/Position2D.global_position
    
        bullet.velocity = get_global_mouse_position() - bullet.global_position