Set projectiles position

I’m making a enemy that starts shooting at player whe it sees them, but currently the bullets are spawning outside of the enemiy’s sprite
How can I change the spawn point location?
My current code:

extends Node2D

#@onready var main = get_tree().get_root().get_node("main")
@onready var bullet = preload("res://objects/shot.tscn")
var can_shoot = false

# Called when the node enters the scene tree for the first time.
func _ready():
	$AnimatedSprite2D.play("default")

func _physics_process(delta: float) -> void:
	if can_shoot ==  true:
		var bullet_temp = bullet.instantiate()
		bullet_temp.direction = -1
		add_child(bullet_temp)
		can_shoot =  false

# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass


func _on_area_2d_body_entered(body):
	if body.get_name() == "Player":
		#shoot()
		$Timer.start()

func _on_timer_timeout():
	can_shoot = true


func _on_area_2d_body_exited(body):
	can_shoot =  false`Preformatted text`

There’s a couple of approaches, that I know of, that enables you to reposition a newly instantiated scene in the same frame.

Approach #1: Deferred call

Since the node is added to the tree at the end of the frame (i.e. at idle time), you can’t yet set the position of the node. However, you can use set_deferred() or call_deferred() to delay the assignment or call of a function to idle time where the child has been added.

var bullet_temp = bullet.instantiate()

# Deferred assignment
var new_position: Vector2
bullet_temp.set_deferred("global_position", new_position)

Approach #2: Moving spawn logic to the Bullet class

If you have a complex initialization routine for your bullet class – or you simply don’t want/need to use set_deferred() – you can add a function to your bullet class that position’s the bullet once it has been added to the tree.

var bullet_temp = bullet.instantiate()

var new_position: Vector2
bullet_temp.initialize(new_position)

…where initialize() is declared in your Bullet class. For example:

class_name Bullet

var initial_position: Vector2

func initialize(initial_position: Vector2):
	self.initial_position = initial_position

# Executes when the node has entered the tree.
func _enter_tree():
	global_position = initial_position

I hope this helps. Let me know if you have any further questions.

The first option doesn’t work, while the second option does change the bullets spanw location, but I don’t know how to set it to be exactly where I want

Sounds like your enemy and/or bullet scene are offset from (0, 0). Could you share a screenshot of your bullet and enemy scene’s 2D view?

Better to not child bullets too, though this won’t solve anything if there is an offset

func _physics_process(delta: float) -> void:
	if can_shoot ==  true:
		var bullet_temp = bullet.instantiate()
		bullet_temp.direction = -1

		bullet_temp.global_position = global_position #
		add_sibling(bullet_temp) #

My Bullet scene:


My enemy scene

Looks like both are off center. Notice your enemy is not on the red/green intersection? The bullet is 225 pixels off the X axis and 125 pixels off on the Y. Your scenes should be at the origin (0, 0).

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.