Bullet/sword not spawning

Hi, I’m trying to fire a bullet (or a sword) towards the mouse from the player (knight). I’m fairly new, so I might have missed something obvious, but here is the code inside the knight.

extends Node2D

setup shoot

signal shoot(bullet, direction, location)
var bullet = preload(“res://assets/Sword.png”)

func fire():
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
shoot.emit(bullet, rotation, position)

get cursor position

func _process(delta):
look_at(get_global_mouse_position())

fire from the knight

func _on_knight_shoot(bullet, direction, location):
var spawned_bullet = bullet.instantiate()
add_child(spawned_bullet)
spawned_bullet.rotation = direction
spawned_bullet.postion = location
spawned_bullet.velocity = spawned_bullet.velocity.rotated(direction)

When I click, no bullets/swords spawn.

Other things to note: I created a script in bullets and a timer node. The timer is three seconds.

extends CharacterBody2D

func _on_slifespan_timeout():
queue_free()

I tried to link the _on_knight_shoot to a the main node, but GODOT tells me it cannot connect the signal.

Do like this:

get_tree().current_scene.add_child(spawned_bullet)

I’m not sure where to put this.
I replaced add_child(spawned_bullet), but when I tested, nothing worked.

Can you paste your script between ticks like so, and point out which line gave you the error? Does the error appear while playing the game? is it a stack trace?

```
type or paste code here
```

I’m not getting an error anywhere. There’s nothing that appears in game. I click and there’s no bullet/sword

I’m not sure what I mean, but here’s the new code for _on_knight_shoot

func _on_knight_shoot(bullet, direction, location):
var spawned_bullet = bullet.instantiate()
get_tree().current_scene.add_child(spawned_bullet)
spawned_bullet.rotation = direction
spawned_bullet.postion = location
spawned_bullet.velocity = spawned_bullet.velocity.rotated(direction)
print(“shoot”)

I also typed print(“shoot”) And nothing appears in the console when I click

Ah right, you cannot connect the signal, so that function never fires. Does it say anything about why it cannot connect the signal? They both share three arguments.

No errors come up, and it doesn’t tell me anything about the signals.

Also, I put print(“shoot”) in the fire() function, and again, I get no message in the console.

func fire():
if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
shoot.emit(bullet, rotation, position)
print(“shoot”)

Where did you called the fire function?

1 Like

Make sure to paste code with formatting, the </> button will create three ticks for you. Or selecting your pasted code and pressing ctrl+e

I think you want to merge your _process and fire functions

func _process(delta: float) -> void:
    look_at(get_global_mouse_position())
    if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
        shoot.emit(bullet, rotation, position)
1 Like

Thanks for the advice.

func _process(delta: float) -> void:
	look_at(get_global_mouse_position())
	if Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT):
		shoot.emit(bullet, rotation, position)
		print("shoot")

Anyways, I input print(“shoot”) and it displays in the console.

However, if I input print(“shoot”) like I did before in _on_knight_shoot, it still does not display on the console.

func _on_knight_shoot(bullet, direction, location):
	var spawned_bullet = bullet.instantiate()
	get_tree().current_scene.add_child(spawned_bullet)
	spawned_bullet.rotation = direction
	spawned_bullet.postion = location
	spawned_bullet.velocity = spawned_bullet.velocity.rotated(direction)
	print("shoot")

Have you connected it properly?

I have connected it to knight below everything else.

If I try to connect to the parent (The game/main) node of knight, I get “Cannot Connect Signal”. I do have a script for/in the parent node.

Okay, I have no idea what I did, but I got an error

Invalid call. Nonexistent function ‘instantiate’ in base ‘CompressedTexture2D’

At function: _on_shoot
At function: _process

I did change the code by removing “knight” from _on_knight_shoot.

func _on_shoot(bullet, direction, location):
	var spawned_bullet = bullet.instantiate()
	get_tree().current_scene.add_child(spawned_bullet)
	spawned_bullet.rotation = direction
	spawned_bullet.postion = location
	spawned_bullet.velocity = spawned_bullet.velocity.rotated(direction)
	print("shoot")

ah so it was trying to connect to _on_shoot I suppose.

Your bullet is a Sword.png, not the bullet .tscn you made

I don’t understand, I don’t have .tscn in the code.

You instantiated a Sword.png file, do you have a Sword.tscn file that you can instantiate? I’m new to Godot but I’ve only instantiated scenes.

var bullet = preload("res://scene/sword.tscn")

Okay, I’ve changed it, and now I get a different error:

Invalid set index ‘position’ (on base: ‘CharacterBody2D (bullet.gd)’) with value of type ‘Vector2’

At function: _on_shoot
At function: _process

I notice this line is postion instead of position, missing the first i

spawned_bullet.postion = location

But the error you posted is not missing an i

Could you post the line the error appears on too?

func _on_shoot(bullet, direction, location):
	var spawned_bullet = bullet.instantiate()
	get_tree().current_scene.add_child(spawned_bullet)
	spawned_bullet.rotation = direction
	spawned_bullet.position = location
	spawned_bullet.velocity = spawned_bullet.velocity.rotated(direction)
	print("shoot")

Okay, I tried it, and it works! . . . Kind of.
It displays on the console and the sword spawns in, however, the sword doesn’t move and it’s a solid object.

Cool! Your sword is a CharacterBody2D, this type will stop other physics objects. If you only want to detect collision use an Area2D.

It doesn’t move because there is no code to move it. You will have to add a process function to the bullet/sword’s script.

# runs every frame, delta is the time between frames
func _process(delta: float) -> void:
    pass # your movement code

If you want to continue with a character body then it should use velocity and move_and_slide() like so

const SPEED = 600

func _process(delta: float) -> void:
    velocity = Vector2.RIGHT.rotated(rotation) * SPEED
    move_and_slide()

If you switch to an Area2D then you need to alter the position youself, not much different though.

const SPEED = 600

func _process(delta: float) -> void:
    position += Vector2.RIGHT.rotated(rotation) * SPEED * delta