Make script work relatively on Instantiated Objects

Hi,

I have a question regarding instantiated objects and the scripts attached to it.
To develop my unity and c# skills I’m creating a simple tower defence.

I’ll try to explain my problem as carefully as possible.

What I have now is that when I click one of the 4 buildlocations on the ground it spawns a machine gun turret that will look for enemies close enough and then rotate towards it.

The code I’m using for that is this:

using UnityEngine;
using System.Collections;

public class turretMove : MonoBehaviour
{
	public float RotationSpeed;
	public GameObject curEnemy;
	private Transform Target;
	private Quaternion _lookRotation;
	private Vector3 _direction;
	private float tmpHealth;
	private string idleT = "mg_reset";

	void FindClosestEnemy() {
		Target = GameObject.Find (idleT).transform;
		GameObject[] gos;
		gos = GameObject.FindGameObjectsWithTag("enemy");
		GameObject closest;
		float distance = Mathf.Infinity;
		Vector3 position = transform.position;
		foreach (GameObject go in gos) {
			Vector3 diff = go.transform.position - position;
			float curDistance = diff.sqrMagnitude;
			if (curDistance < distance && Target.name == idleT) {

					curEnemy = go;
					
					Target = go.transform;
					distance = curDistance;
					if (distance > 300)
				{ Target = GameObject.Find (idleT).transform; }
			}


		}



	}

	void Update()

		{
	
		FindClosestEnemy();

		_direction = (Target.position - transform.position).normalized;
		
		_lookRotation = Quaternion.LookRotation(_direction);

		_lookRotation.x = 0;
		_lookRotation.z = 0;

		transform.rotation = Quaternion.Slerp(transform.rotation, _lookRotation, Time.deltaTime * RotationSpeed);
	}
}

To clarify I’m using a “mg_reset” object (which is a cube) as a reset position. So when no enemies are close enough it will face that cube.

Now this code is working fine except for one thing.
When I build another turret it doesn’t use its own “mg_reset” cube, but the one of the first build turret.

I will try explaining it using an image:

In this image the turret in the bottom left corner was created first. There are no enemies close enough to any of the turret so they should all face their own little reset cube. But as you can see in the image they are all facing the “mg_reset” of the first craeted turret. (red lines show the direction they are facing, but which they shouldn’t and green lines are showing the direction they should be looking).

So my question is basically how do I make instantiated objects use their own object tree? Should I even be using Find() for that? What is the best way to make scripts relative to instantiated objects?

I hope I have clarified this enough and seeing as this is my first question about Unity and on this website I hope I have done everything according to the rules and formats of this forum/answers. (If someone can link me the rules of this forum that would be great btw)

Also if anyone has any general comments about my code that is greatly appreciated, seeing as I’m still trying to figure out my workflow.

I hope I get an answer soon :slight_smile:

Thanks in advance,

Pixelated

GameObject.Find() will return the first object it finds in the hierarchy.

The easiest way to fix this would be to have the “mg_reset” cube as part of the prefab. That way you could make the variable public and assign it via the inspector on the prefab.

If the tower and the reset cannot be on the same prefab then you could still make the reset public and assign it via script on instantiation.

Another interesting alternative would be to tag the reset, then use FindGameObjectsWithTag to get all of them. Then run it through your distance sorting algorithm to find the closet reset. For learning value you could refactor your code so you only have one FindClosest method that works in both circumstances.