Every time I edit a variable in the enemy I have collided with it affects every duplicate of that enemy

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

The title says it all, I am writing a script that changes the size of enemies but when I touch the enemy every enemy grows not just the one I am touching.

func _on_Hit_body_entered(body):
	body.radius += 50

very simple but doesn’t work on just the one I touch. Is there a way to have prefabs like unity that have their own instance of the script so this doesn’t happen?

How are you instancing enemies?
Are the enemies a scene?

deaton64 | 2021-01-11 17:11

The enemy is a scene and I add it to the game multiple times

JiaoZiKai | 2021-01-11 17:27

Can you paste some code how you are doing this please?
Or the project, if you can.

deaton64 | 2021-01-11 17:32

here are the two scripts that interact,

Player script

extends KinematicBody2D


var radius = 25
var pos = Vector2(0,0)
var col = Color(0,0,0)

var moveSpeed = 3
var movement = Vector2()
var maxSpeed = 4

var isShrinking = false
var isGrowing = false

func _draw():
	draw_circle(pos, radius, col)
	pass


func _process(delta):
	#$CollisionShape2D.shape.radius = radius
	#$Hit/CollisionShape2D.shape.radius = radius + 50 #this is the one with problems
	
	if $Hit/CollisionShape2D.shape.radius != radius + 1:
		_update_colliders()
	
	if Input.is_action_pressed("d"):
		movement.x += moveSpeed
	elif Input.is_action_pressed("a"):
		movement.x -= moveSpeed
	else :
		movement.x = 0
		
	if Input.is_action_pressed("w"):
		movement.y -= moveSpeed
	elif Input.is_action_pressed("s"):
		movement.y += moveSpeed
	else :
		movement.y = 0
	

	if Input.is_action_just_pressed("ui_up"):
		radius += 5
	elif Input.is_action_just_pressed("ui_down"):
		radius -= 5

	move_and_slide(movement)
	update()
	
	if isShrinking:
		_shrink()
	if isGrowing:
		_grow()
	
	pass

func _update_colliders():
	$Hit/CollisionShape2D.shape.radius = radius + 1
	$CollisionShape2D.shape.radius = radius

func _shrink():
	print("SHRINKING!")
	radius -= 1
	if radius <= 0:
		_die()
	#$Hit/CollisionShape2D.shape.radius = radius + 5

func _grow():
	print("GROWING!")
	radius += 1
	#$Hit/CollisionShape2D.shape.radius = radius + 5

func _die():
	queue_free()


func _on_Hit_area_entered(area):
	if area.get_parent().radius > radius:
		#isShrinking = true
		#area.get_parent().isGrowing = true
		pass
	elif area.get_parent().radius < radius:
		#isGrowing = true
		#area.get_parent().isShrinking = true
		pass
	#print(area.CollisionShape2D.shape.radius)


func _on_Hit_area_exited(area):
	isGrowing = false
	isShrinking = false
	area.get_parent().isShrinking = false
	area.get_parent().isGrowing = false
	


func _on_Hit_body_entered(body):
	print("body entered")
	body.radius += 50

enemy script

extends KinematicBody2D


var radius = 15
var pos = Vector2(0,0)
var col = Color(0,0,1)

var moveSpeed = 3
var movement = Vector2()
var maxSpeed = 4

var isShrinking = false
var isGrowing = false

func _draw():
	draw_circle(pos, radius, col)
	pass


func _process(delta):

	if $Area2D/CollisionShape2D.shape.radius != radius:
		_update_colliders()
	

	#move_and_slide(movement)
	update()
	
	if isShrinking:
		_shrink()
	if isGrowing:
		_grow()
	
	pass

func _update_colliders():
	$CollisionShape2D.shape.radius = radius
	$Area2D/CollisionShape2D.shape.radius = radius

func _shrink():
	print("SHRINKING!")
	radius -= 1
	if radius <= 0:
		_die()
	_update_colliders()
	#$Hit/CollisionShape2D.shape.radius = radius + 5

func _grow():
	print("GROWING!")
	radius += 1
	_update_colliders()
	#$Hit/CollisionShape2D.shape.radius = radius + 5

func _die():
	queue_free()

func _activate_shrink():
	isShrinking = true
func _activate_grow():
	isGrowing = true

func _on_Area2D_area_entered(area):
	#if area.get_parent().radius > radius:
		#isShrinking = true
	#elif area.get_parent().radius < radius:
		#isGrowing = true
	pass


func _on_Area2D_area_exited(area):
	isGrowing = false
	isShrinking = false

I built this in unity in 5 minutes but I am not sure what I am doing wrong in godot

JiaoZiKai | 2021-01-11 17:46

sorry I just reviewed this code and it is pretty messy from my trying new things

JiaoZiKai | 2021-01-11 17:49

How are you getting the enemies into the scene?
if you are duplicating them within the editor, then that could be your problem.
Add them with code:

var nme = load("res://nme.tscn")
nme1 = nme.instance()
add_child(nme1)

deaton64 | 2021-01-11 18:00

Ah, so every enemy I would like to place in a game needs to be added by code? should I create a new node that loads itself as the enemy scene?

JiaoZiKai | 2021-01-11 18:14

I tried this code and it created a new instance but when I collide it still makes all of the others grow too

JiaoZiKai | 2021-01-11 18:21

That’s what I do, I can track them all that way.
Have a Google, there should be a ton of tutorials for this.

deaton64 | 2021-01-11 18:21

cool cool, I have searched a bunch but maybe I am searching the wrong things… Thanks for the time man, I will see what I can figure out and try a new project and if I can’t get it maybe I will just go back to unity

JiaoZiKai | 2021-01-11 18:29

Yes, it’s all about what you feel comfortable with. I started with Unity, went to GameMaker, then Defold, back to Unity and then Godot.
I like Godot, I prefer it to all the others I’ve used. It doesn’t mean it’s the best, I just feel comfortable with it.

deaton64 | 2021-01-11 22:25

sprite duplication in godot is really weird

Amateur.game.dev. | 2021-01-14 17:59

:bust_in_silhouette: Reply From: EXOMODE

Here is an example of a universal prefab loader with caching and fault tolerance. It is part of my modified asynchronous resource loader. The above method will return the original instance at the first moment of loading, cache the instance, and then return independent duplicates when you re-access it (which is what you need to solve your problem). The method will work with any type of resource

var _cache: Dictionary = {}
var _duples: Array = []

func load_unique_resource(path: String):
	if _cache.has(path) and is_instance_valid(_cache[path].instance):
		if path in _duples:
			return _cache[path].instance.duplicate()
			
		_duples.append(path)
		return _cache[path].instance
		
		var f: File = File.new()

		if f.file_exists(path) or ResourceLoader.exists(path):
			var r = ResourceLoader.load(path)
			
			if not r.has_method("instance"):
				if r.has_method("duplicate"):
					return r.duplicate()
				
				return r
			
			_cache[path] = { path = path, loader = r, instance = r.instance() }
			_duples.append(path)
			return _cache[path].instance
		
		return null