Where to attach particle effects on Node

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By kickinespresso

I have a Ball Entity in the game that bounces around off of props. When the Ball Entity collides with another prop, I want to add a particle effect indicating the impact. When I do this in the _physics_process it seems to lag the game a little when impacting or adding the particle effect to the Ball. I wanted to know where is the best place to add the particle effects so they don’t interfere with the performance.

I have a Ball Entity Scene setup as:

- Ball
-- CollisionShape2D
-- Sprite

The Ball Entity Scene Script _physics_process and explosion function to add the particle effect:

func _physics_process(delta):
	"""
	Physics Update
	"""
	var original_position = position
	var collision = move_and_collide(direction * delta)
	if collision:
		direction = direction.bounce(collision.normal)
		if collision.collider.is_in_group("paddles"):
	
			var x = direction.x/2 + collision.collider_velocity.x
			direction = Vector2(x, direction.y).normalized() * (ball_speed + hit_counter + speed_commulator)
			# Win Condition?
			if hit_counter < max_hit_count:
				hit_counter += 1
				
			explode(collision.position, original_position)
		if collision.collider.is_in_group("props"):
			explode(collision.position, original_position)

func explode(collision_position, incoming_position):
	"""
	Generate a Particles Effect to indicate the ball contacting an object
	"""
	#var explosion = ResourceLoader.load("res://effects/ContactExplosion.tscn")
	var explosion = ResourceLoader.load("res://effects/bounce_explosion/BounceExplosion.tscn")
	var exp_inst = explosion.instance()
	var this_sprite = get_node("Sprit" + "e")
	this_sprite.hide()	
	#print("x: ", collision_position.x, " y: ", collision_position.y)

	exp_inst.position = collision_position
	exp_inst.look_at(incoming_position)
	var current_scene = get_tree().get_current_scene()
	current_scene.call_deferred("add_child", exp_inst)

The way it works now, if a collision is detected in the _physics_process the ball direction is changed and the explosion function is called to add the explosion particle effect. (The particle effect cleans it self up after it has run once). Should I be doing this differently?

Have you thought of using a signal? When the ball comes in contact with a certain surface, have the particle effect go off. Also, it would be a good idea to first load the resource (i.e. in your _ready() function) and then instance it when necessary.

Ertain | 2020-03-14 15:24

:bust_in_silhouette: Reply From: jgodfrey

I’d guess the main lag is caused by the fact that you’re loading the scene each time it’s needed using this:

var explosion = ResourceLoader.load("res://effects/bounce_explosion/BounceExplosion.tscn")

The first change I’d make is to preload that scene in _ready and simply spin up instances of it in your explode function. That’ll likely be a big improvement.

Beyond that, is there only 1 of these particle systems on-screen at any given time? If so, you could simple create a single instance of the particle system and hide/show it when/where necessary.

Unrelated, but curious what this is about?

var this_sprite = get_node("Sprit" + "e")