Script only works in one object

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

I have two objects that are basically the same one, basically coins, but I have a problem cause the script that the object has, only works with the first I added to the scene and affects the other one without touching it.

Basically my script is something like this
func _on_Area2D_body_entered(): queue_free() print("Coin collected!")

Is there a way to make the script work only with the object that the player touched?

:bust_in_silhouette: Reply From: Coweh

I’m not completely sure, but if I had to guess, you’re instancing the coins, and since instances share everything, that’s why the script affects the other coin. Right-clicking on the nodes and pressing “make local” should work, it will make the nodes local and therefore they won’t affect each other.

Is not working. Doesn’t work if the node is Area2D?

Repertix | 2020-10-05 04:27

In that case, I’m not completely sure. Could you give a few more details?

Coweh | 2020-10-05 15:54

Well, the coin is created from a specific scene, all I just do is insert that scene as an object in the level. As you commented to me before, I tried clicking “Make local” but didn’t work. The coin is an Area2D with Sprite and Collision Shape 2D, the Area2D has a signal connected to the Player to detect when is being touched to then increase the number of coins, while in the Area2D script makes it disappear. There’s something in the object that makes it act like that?

Repertix | 2020-10-05 20:24

Nvm, apparently your method works, but when I try to emit a signal it only does with the first coin.

Repertix | 2020-10-06 01:27

“make local” is a editor helper. the scene should be saved as “coin.tscn”, then instanced.
duplicate with ctrl+d or command+d (mac). or drag and drop to viewport. Or instance with procedural script.

extends Node

onready var c = preload("res://coin.tscn")

func _ready():
    var coin_instance = c.instance()
    add_child(coin_instance)

razah | 2020-10-06 13:07

:bust_in_silhouette: Reply From: razah

assign the coin node to the “coin” group and connect this signal to the player’s Area2D. it will only destroy the coin it touched.

func _on_player_area_entered(body):
	if body.is_in_group("coin"):
		print("Coin collected")
		body.queue_free()

The player is not an Area2D, could work if I put the Area2D with a CollisionShape2D inside a KinematicBody2D?

Repertix | 2020-10-06 00:03

Yes. Or you can connect the signal to coin(Area2D).
You can receive a signal when the kinematic body enters, here detailed information
Area2D — Godot Engine (stable) documentation in English

razah | 2020-10-06 12:52