GameObject not being Instantiated correctly when called from another script.

Hello everyone :slight_smile:

I am having a problem with my build script where my turrets are not being built where I want them.
It works perfectly when I call the build function from the same script, but once I call it from another script, the turret always gets build on Node 1.

I’m not really good at explaining, but hopefully you understand what I am trying to achieve :slight_smile:

Here is the code where I Instantiate the turret:

using UnityEngine;

public class Node : MonoBehaviour {

    public Color HoverColor;
    private Renderer rend;
    public Transform rendTransform;
    private Color startColor;
    private GameObject turret;
    public Vector3 positionOffset;

    void Start () {
       
        rend = GetComponent<Renderer>();
        rendTransform = GetComponent<Transform> ();
        startColor = rend.material.color;
    }

    void OnMouseEnter()
    {
        rend.material.color = HoverColor;
    }

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

    void OnMouseDown()
    {
        BuildTurret ();
    }

    public void BuildTurret()
    {
        if (turret != null) {
            Debug.Log ("Turret already build here.");
            return;
        }
            GameObject turretToBuild = BuildManager.instance.GetTurretToBuild ();
            turret = (GameObject)Instantiate (turretToBuild, rendTransform.transform.position + positionOffset, rendTransform.transform.rotation);
    }
}

A node is a square box where the player is allowed to place a turret.
This code now places a turret where the cursor is. However, I don’t want to use mouse clicking as my building method. Instead I want to use a drag and drop system which I already have made.

This code is from another script which handles the dragging of UI elements to place turrets.

public void OnEndDrag (PointerEventData eventData)
    {
       
        transform.position = startPosition;


        if (itemBeingDragged != null) {

            if (itemBeingDragged.transform.tag == ("TurretTier1")) 
            {
                    itemBeingDragged.gameObject.SetActive (false);
                    HoldingTurretCard = false;
                    nodeScript.BuildTurret ();
            }

        } else 
        {
            itemBeingDragged = null;
            return;
        }
    }

When I’m doing this, the turret always gets built on node 1. Why?
Please ask if you want any more information. Sorry I’m bad at explaining, but I’m trying my best :smile:

How is the field nodeScript getting set? Is it possible that nodeScript always references node 1?

I’m using public Node nodeScript
thats all…

With Node being the node script of course

I guess the problem is that its only looking for the Node script in the first node in the list…?

Ah, since it’s a public field, then it just matters which object you dragged into the field in the inspector. Don’t think of that field as being “the node script” itself, but a specific instantiation of the node script. You can have multiple instantiations of course, and since you have multiple nodes, you therefore have multiple instantiations. That field called “nodeScript” is only referencing a single one of these, and it is the one whose transform is being used to determine the position at which the turret gets built.

What you need to do is find out at the end of the drag which specific node is the target of the drag, and use that instance to call BuildTurret().

Sorry for the late reply :stuck_out_tongue:
I fixed this by raycasting from the mouse and checking for tags :slight_smile:
Thanks for helping me out :slight_smile: