Smoke doesn't want to follow muzzle position

Godot 4.2.1

Hi,

I have, what it seems at first very simple problem.
When i shoot, the smoke is generated, but it stays in place instead of following the Muzzle.

This is smoke scene that is preloaded:
@onready var SmokeScene = preload("res://scenes/effects/smoke.tscn")

func _physics_process(_delta):
	handleInput()

This is my function for handling input:

func handleInput():
	var moveDirection = Input.get_vector("left", "right", "up", "down")
	if Input.is_action_just_pressed("shoot") and not is_reloading:
		if current_bullets_in_magazine > 0:
			if current_fire_mode == FireMode.SINGLE:
				shoot()
			elif current_fire_mode == FireMode.BURST:
				burst_shoot()
	elif Input.is_action_pressed("shoot") and not is_reloading and current_fire_mode == FireMode.AUTO:
		if current_bullets_in_magazine > 0 and can_shoot_auto:
			shoot_auto()
	elif Input.is_action_just_pressed("reload"):
		reload()
	elif Input.is_action_just_pressed("toggle_fire_mode"):
		toggle_fire_mode()
	
	velocity = moveDirection * speed

This is function shoot:

func shoot():
	muzzleFlash.visible = true
	AnimationsMuzzleFlash.play("flash")
	gunshot.play()
	var direction = null
	if is_using_mouse():
		var mouse_position = get_global_mouse_position()
		direction = (mouse_position - global_position).normalized()
		gun_recoil(10, crosshair)
	else:
		start_rumble(0.1, 1, 1)
		direction = (crosshair.global_position - global_position).normalized()

	var spread = 200.0 / crosshair.CROSSHAIR_1
	var bulletSpreadAngle = deg_to_rad(spread)
	direction = applySpread(direction, bulletSpreadAngle)

	var bullet = Bullet.instantiate()
	add_child(bullet)
	bullet.global_position = muzzle.global_transform.origin
	bullet.rotation = direction.angle()
	knockback_recoil(direction)
	smoke()

and smoke:

func smoke():
	var smokeNode = SmokeScene.instantiate()
	add_child(smokeNode)
	smokeNode.global_position = muzzle.global_position
	var smoke_particles = smokeNode.get_node("SmokeParticles")
	smoke_particles.emitting = true

smoke.gd looks like this:
extends Node2D

func _ready():
	var timer = Timer.new()
	timer.wait_time = 5.0
	timer.one_shot = true
	add_child(timer)
	timer.connect("timeout", Callable(self, "_on_timer_timeout"))
	timer.start()

func _on_timer_timeout():
	queue_free()

This is my structure:
Player (characterbody2d)

  • Weapon (node2d)
    • Muzzle (Marker2D)

Whatever i do the smoke doesn’t follow the muzzle. If i put “smoke” scene into _physics_process then it follows, but it’s of course generted continually. The problem i have is that there are multiple objects not a single one.

Do you have any ideas?

Thank you.

Instead of adding smoke to player and position it on muzzle, add smoke to the muzzle

muzzle.add_child(smokeNode)

This should make the smoke follow the muzzle.

If you haven’t already you may need to set the particle emitter to allow emitted particles to not follow parent transform.

1 Like

Thanks, the thing I changed for particle effect is: Drawing → Local Coords set to true, and now it follows.

I find out that this is not what I wanted. What I wanted is the explosiveness parameter set to lower value as it create this smoke that follow a gun.