Finding the gameobject a gameobject is placed on? (C#)

Hey everyone. I have a big problem with my upgrade turret script.
First, I’ll tell you how I’ve got things set up.

  • I have 256 nodes on my map. (The nodes are places I can place my turrets.) They all have a script attached to them. This script is for placing a turret on the selected node and handling the upgrades of each turret.

  • Second, I have a script which checks if the player pressed a upgradable turret and starts a function in the script.

My problem is that when I select a upgradable turret and press the upgrade button, the new turret is placed on node 1 of 256. And not the node the upgradable turret is placed on. This is because my script is using GameObject.FindObjectOfType(); And this will always return node 1 of 256.

So I need to know how I can find the node the turret is placed on and place the new turret there.

Here are the scripts I’m using:

Node.cs:

    using UnityEngine;
    using UnityEngine.EventSystems;
    using UnityEngine.UI;
 
    public class Node : MonoBehaviour {

	public Color hoverColor;
	public Vector3 positionOffset;
	public GameObject UpgradeTurret1UI;
	public bool Upgraded;
	public GameObject TurretLevel2Prefab;

	[Header ("Optional")]
	public GameObject turret;

	private Renderer rend;
	private Color StartColor;
	BuildManager buildManager;

	void awake()
	{
		UpgradeTurret1UI = GameObject.Find("UpgradeNormalTurretLvl2");
	}

	void Start()
	{
		rend = GetComponent<Renderer> ();
		StartColor = rend.material.color;
		buildManager = BuildManager.instance;

		UpgradeTurret1UI.SetActive (false);
	}

	public Vector3 GetBuildPosition()
	{
		return transform.position + positionOffset;
	}

	void OnMouseUp ()
	{
		if (EventSystem.current.IsPointerOverGameObject()) 
			return;

		if (!buildManager.CanBuild)
			return;

		if (turret != null) 
		{
			Debug.Log("Turret already placed here.");
			if (turret.tag == "TurretTier1") {
				Turret1Upgrade ();
			} else
				return;
		}

		//build a turret
		buildManager.BuildTurretOn (this);
	}

	void OnMouseEnter ()
	{
		if (EventSystem.current.IsPointerOverGameObject()) 
			return;
		

		if (!buildManager.CanBuild)
			return;
		
		GetComponent<Renderer> ().material.color = hoverColor;
	}

	void OnMouseExit()
	{
		rend.material.color = StartColor;
	}

	public void ExitButtonPressed()
	{
		UpgradeTurret1UI.SetActive (false);
		Time.timeScale = 1;
	}
	 
	public void Turret1Upgrade()
	{
		Debug.Log ("This is a Standard Turret.");
		UpgradeTurret1UI.SetActive (true);
		Time.timeScale = 0;
		return;
	}

	public void UpgradeButtonPressed()
	{
		if (MoneyManager.money >= 60) {
			Instantiate (TurretLevel2Prefab, transform.position, transform.rotation);
			MoneyManager.money -= (60);
			Upgraded = true;
			Debug.Log ("UpgradeButton pushed.");
			UpgradeTurret1UI.SetActive (false);
			Time.timeScale = 1;
			Debug.Log ("Working...");

		} else
			Debug.Log ("Not enough cash to upgrade this turret.");
			return;
	}
     }

Here is my “ClickTurret1.cs” script:

         using UnityEngine;
        using System.Collections;

        public class ClickTurret1 : MonoBehaviour {

	private Node node;

	void Awake()
	{
		node = GameObject.FindObjectOfType<Node>();
	}
	void OnMouseUp()
	{
		node.Turret1Upgrade ();
	}
        }

And lastly, if its needed, this is my BuildManager script this determining where to place the turret based of which node is pressed.
“BuildManager.cs”:

       using UnityEngine;


        public class BuildManager : MonoBehaviour {

	public static BuildManager instance; 


	void Awake ()
	{
		instance = this;
	}

	public GameObject standardTurretPrefab;
	public GameObject SateliteTurretPrefab;
	public GameObject MissileLauncherPrefab;
        public GameObject DrillGoldDiggerPrefab;
	public GameObject TeslaCoilPrefab;
	public MoneyManager moneyManager;
	public GameObject turret;
	private TurretBlueprint turretToBuild;

	public bool CanBuild{ get { return turretToBuild != null;}}


	public void SelectTurretToBuild(TurretBlueprint turret)
	{
		turretToBuild = turret;
		return;
	}

	public void BuildTurretOn(Node node)
	{
		if (MoneyManager.money <= turretToBuild.cost) 
		{
			Debug.Log ("Not enough money");	
			return;
		}
		MoneyManager.money -= (turretToBuild.cost);
		GameObject turret = (GameObject)Instantiate (turretToBuild.prefab, node.GetBuildPosition (), Quaternion.identity);
		node.turret = turret;
	}

        }

Any help would be very very appreciated. Thanks in advance.

  • Joe

Problem is not solved yet and I could really use some more help! :S

You could instantiate the turret as child of node gameobject in your BuildManager script:

GameObject turret = (GameObject)Instantiate (turretToBuild.prefab, node.GetBuildPosition (), Quaternion.identity); turret.transform.parent = node.gameobject.transform;

Now your turret always knows what node is the parent.

You are correct your main issue is going to be that you are using FindObjectOfType. This is not what you want. I would recommend avoiding this type of search. If you have your click script on each node then a GetComponent<Node>() would be the way to go.

Now as for your problem. When you say it is appearing on node 1 do you mean visually it is in the wrong place in the game screen, or that in your game hierarchy you game objects are not attaching to the correct parent?

Is your hierarchy a nice organised tree structure where turrets are children of their node parents or are you ending up with one big long list of game objects?

Currently you are creating turrets in your BuildManager but you are not assigning them as children of the node you want them on. Keeping your game objects organised and parented correctly is going to be a big help in the long run.

So my suggestion would be you Instantiate you turret to its parent node directly. So that your turrets position is inherited by the parent child relationship that way you don’t have to position it, its just created in the correct spot to begin with (assuming your nodes are where you want them).

So to do this change your BuildManager to this

    public void BuildTurretOn(Node node)
     {
         if (MoneyManager.money <= turretToBuild.cost) 
         {
             Debug.Log ("Not enough money");    
             return;
         }
         MoneyManager.money -= (turretToBuild.cost);
         node.turret = (GameObject)Instantiate (turretToBuild.prefab, node.transform);
     }
}

This all does rely on your ability to find and pass the correct node to the function.