Search Unity

Accessing an instantiated object from another script

Discussion in 'Scripting' started by jrauden, Apr 28, 2017.

  1. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Ok, I'm fairly new to coding and i have searched everywhere for the answer to this but i can't find it. I'm simply trying to make a GameObject (instantiated clone) from one script follow a GameObject (instantiated clone) from another script. here is what i have.

    I have 2 scripts: scriptA & scriptB.

    In script A I instantiate a gameObject called player:
    ________________________________________________________________________
    public GameObject player;

    void Start() {
    GameObject player = Instantiate (player, new Vector3 ((int)Random.Range(-6f,6f), (int)Random.Range(-4f,4f), 0), Quaternion.identity);
    }
    // does it matter that my prefab is called player?
    // it looks strange that i have player as a variable, then use player again in Instantiate?
    ________________________________________________________________________

    Now, i want to access that instantiated object (the clone), from scriptB, so in scriptB I have:
    ________________________________________________________________________
    public GameObject target; //i drag my prefab into this slot in unity

    void Update () {
    this.transform.position = target.transform.position; // i was hoping this would make "this" transform always be the same as target.transform
    }
    ________________________________________________________________________

    the problem i have is that this.transform.position is accessing the transform.position of my prefab, 0,0,0. How do i get the clones position and not the prefab's position?

    At some point in this process i was able to make the this.transform.position equal to the transform.position of player.....the problem was it was changing the transform.position of my prefab. So the next time i ran my program the prefab started out at whatever it's last position was on the last run.

    I know this is probably simple, but for the life of me i can't figure this out. It's like I only know how to access the prefabs, is that because i am dragging my prefabs into the slots in Unity?

    Thank you in advance for any help.

    James
     
  2. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    You need to use code tags. Also don't instantiate your player prefab into a local variable of the same name ("player"). You don't want to try to follow the position of the prefab, you need some reference to the actual GameObject within the scene that you want to follow. There's lots of ways to do that.

    What GameObject is Script A attached to for starters?

    Here's an example though

    Script A attached to a GameObject within the scene, where that game object has a tag assigned of "SceneObject"

    Code (csharp):
    1.  
    2. public GameObject playerPrefab;
    3. public GameObject player1;
    4.  
    5. void Start()
    6. {
    7.     player1 = instantiate(playerPrefab, new Vector3 ((int)Random.Range(-6f,6f), (int)Random.Range(-4f,4f), 0),
    8. }
    9.  
    Script B attached to some other object that wants to follow player1:

    Code (csharp):
    1.  
    2.  
    3. private GameObject target;
    4.  
    5. void Start ()
    6. {
    7.     target = GameObject.FindObjectWithTag("SceneObject").GetComponent<ScriptA>().player1;
    8. }
    9. void Update ()
    10. {
    11.     gameObject.transform.position = target.transform.position;
    12. }
    13.  
    14.  
    So we instantiate the playerPrefab, which you drag into that slot in the inspector, as the player1 GameObject. This is all done on Script A, which is attached to a GameObject that exists from the start in the scene, or is instantiated by some other script somewhere else. The Script A attached object has a tag of "SceneObject" which we use in Script B.

    Script B is attached to some other object that I'm assuming isn't instantiated until player1 is already instantiated, so that when Script B hits start it can properly assign the target. If Script B exists before player1 is instantiated then you'll have to move assigning target into another method you call later, and don't update gameObject.transform.position until that method is called. For example: (this probably works, but if I messed something up because I don't have Unity on this computer or a C# editor I apologize)

    Code (csharp):
    1.  
    2. private GameObject target;
    3. private targetInitialized = false;
    4.  
    5. void Start ()
    6. {
    7. }
    8. void Update ()
    9. {
    10.     if (targetInitialized)
    11.     {
    12.         gameObject.transform.position = target.transform.position;
    13.     }
    14.     else
    15.     {
    16.         targetInitialized = setTarget();
    17.     }
    18. }
    19.  
    20. private bool setTarget()
    21. {
    22.     target = GameObject.FindObjectWithTag("SceneObject").GetComponent<ScriptA>().player1;
    23.     if (target == null}
    24.     {
    25.         return false;
    26.     }
    27.     else
    28.     {
    29.         return true;
    30.     }
    31. }
    32. public
    33.  
     
    Last edited: Apr 28, 2017
    arethusal likes this.
  3. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Why do you have to get the script of the instantiated object i am trying to follow?
    I dont understand the getcomponent <scriptA> part??? Can you elaborate on what that line of code is doing?


    Thanks for quick reply, will give the tag method a try. I am still wondering though, is there no simple way to access clones that are running around my game board without tags? Say i instantiate 10 Enemy1 clones and then later put all of their positions into an array, is tht best done with tags? Isnt there a way to just search the scene for all enemy clones and simply put their positions in an array?

    Sorry if im missing something, spent my college years learning C++ but this is quite different....and that was many years ago!

    And since you asked, this all began with me trying to get a gameobject to rotate around my player but always stay on his righthand side. I read in this forum to make an empty gameobject that follow my player and then make the orb a child of the empty gameobject. Seems like alot of work for something so simple.
    Thank you sooo much for your help.
     
    Last edited: Apr 28, 2017
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    You don't have to use tags at all, they are just pretty easy. You just need some way to have a reference to the gameobject you're looking for. Another way would be for Script A to both instantiate the player gameobject and also instantiate the gameobject with Script B. Then as soon as Script A instantiates the GameObject with Script B it could set the target on Script B. Set target to be public, or create a public method to assign target on Script B.

    Code (csharp):
    1.  
    2. GameObject ScriptBObject = instantiate (ScriptBObjectPrefab);
    3. ScriptBObject.GetComponent<ScriptB>().target = player1;
    4.  
    You could also have script A assign a reference to itself to the player object or the script b object can access arrays or lists of other objects on script A. Then any player gameobject could look up the entire list of other player gameobjects without having to do any kind of find commands. Just reference ScriptAObjectReference.GetComponent<ScriptA>().LotsOfGameObjectsToAccess whenever you want to look up any of the other ones.

    Code (csharp):
    1.  
    2.  
    3. public List<GameObject> LotsOfGameObjectsToAccess;
    4. public GameObject playerPrefab;
    5.  
    6. void Start ()
    7. {
    8.     LotsOfGameObjectsToAccess = new List<GameObject>();
    9. }
    10.  
    11. private void instantiateAnotherPlayer()
    12. {
    13.     GameObject newPlayer = instantiate(playerPrefab);
    14.     newPlayer.GetComponent<WhateverScript>().ScriptAObjectReference = gameObject;  //tell the new player object how to easily find me
    15.     LotsOfGameObjextsToAccess.Add(newPlayer);  //now add it to the list
    16. }
    17.  
    18.  
     
  5. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Ok, can you explain to me why i need the getcomponent <scriptA> is needed for. I cant quite understand why we are getting the script?

    Thanks again!!
     
  6. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    Generally when you want to access a different script than the one currently executing you do that through GetComponent. This will let you access anything declared as public on that script.
     
  7. jrauden

    jrauden

    Joined:
    Apr 4, 2017
    Posts:
    27
    Thank you for your help sir, greatly appreciated.