Search Unity

  1. Unity 6 Preview is now available. To find out what's new, have a look at our Unity 6 Preview blog post.
    Dismiss Notice
  2. Unity is excited to announce that we will be collaborating with TheXPlace for a summer game jam from June 13 - June 19. Learn more.
    Dismiss Notice

How can I reference to a component of another gameobject?

Discussion in 'Scripting' started by h4di, Nov 16, 2014.

  1. h4di

    h4di

    Joined:
    Jan 26, 2014
    Posts:
    4
    Hi,

    I watched a unity video tutorials on "GetComponent". The tutor assigns two scripts to an object in the scene.
    the first script reads a variable from the second one and prints the value in the console.

    I got how it works. But I don't get how can I read and probably edit components from another game object.
    Let's assume that I have a sphere and a cube. I assign the first script to the sphere and I want that script shows a value from the second script that has been given to the cube.

    But it doesn't work! This is the error that I get:
    NullReferenceException: Object reference not set to an instance of an object
    script1.Awake () (at Assets/script/GetComponent/script1.cs:11)

    Help is truly appreciated.

    first script given to the sphere:
    Code (CSharp):
    1. public class script1 : MonoBehaviour {
    2.  
    3.     public script2 s2;
    4.  
    5.     // Use this for initialization
    6.     void Awake()
    7.     {
    8.         s2 = GameObject.Find ("cube").GetComponent<script2> ();
    9.     }
    10.  
    11.  
    12.     void Start ()
    13.     {
    14.         Debug.Log ("player score is:" + s2.playerScore);
    15.     }
    16.  
    17.  
    18.     // Update is called once per frame
    19.     void Update ()
    20.     {
    21.  
    22.     }
    23. }
    second script has been given to the cube:
    Code (CSharp):
    1.     public int playerScore = 10;
    2.  
    3.     // Use this for initialization
    4.     void Start () {
    5.  
    6.     }
    7.  
    8.     // Update is called once per frame
    9.     void Update () {
    10.  
    11.     }
    12. }
     
  2. MattB79

    MattB79

    Joined:
    Sep 12, 2014
    Posts:
    20
    if the cube is put in the game after the object with script one then the s2 will be null.. in the Awake do a if (s2 == null) Debug.log("s2 is null"); that might be the issue
     
    h4di likes this.
  3. Fluzing

    Fluzing

    Joined:
    Apr 5, 2013
    Posts:
    815
    Several things:

    1. Make sure you actually have an object called "cube:. Find is case sensitive. I prefer using tags by the way.
    2. Do not use GetComponent in the Find, but rather check if the cube actually has been found:

    Code (csharp):
    1.  
    2. CubeScript cube_script;
    3.  
    4. GameObject cube = GameObject.FindWithTag("Cube");
    5.  
    6. if(cube != null)
    7. {
    8.       cube_script = cube.GetComponent<CubeScript>();
    9. }
    10.  
    3. You might want to make score a private and use a Get function, but I guess that is just a matter f preference.

    Code (csharp):
    1.  
    2. public int GetScore()
    3. {
    4.       return playerScore;
    5. }
    6.  
     
  4. h4di

    h4di

    Joined:
    Jan 26, 2014
    Posts:
    4
    @MattB79

    PERFECT, THANK YOU.

    Yes I put the cube after the sphere. So I deleted both objects. Put another cube first and then the sphere. And it is working.

    But I don't get it. Is the order of the objects important?? I totally didn't know about that. Then creating a game object before another one will be totally different from creating after it? And how can I see and check the order of the objects in the scene?

    @Fluzing

    Yes, I made the mistake calling "Cube" with lower case in my code.
     
  5. MattB79

    MattB79

    Joined:
    Sep 12, 2014
    Posts:
    20
    Edit -> project settings -> script execution order. This might work also instead of deleting game objects. And yes its always good to check for nulls like Fluzing posted when using find methods
     
  6. rakesh492

    rakesh492

    Joined:
    Jan 21, 2019
    Posts:
    1
    Thank you so much..you made my day and saved my life also..:)
     
  7. lunaeight08

    lunaeight08

    Joined:
    Oct 29, 2020
    Posts:
    10
  8. SiWoC

    SiWoC

    Joined:
    Feb 16, 2021
    Posts:
    9
    Shouldn't your "s2=" be in Start?
    First all objects are Awakened
    Then they are Started
    So when Start is called, you should be able to find all objects, no matter what order they are in.
     
  9. Owen-Reynolds

    Owen-Reynolds

    Joined:
    Feb 15, 2012
    Posts:
    2,000
    To say it in more detail, when the game starts Unity creates all the gameObjects for the scene. Awake() runs instantly as each one is made: create A, Awake on A, create B, Awake on B ... .. Next, after everything is created, Unity goes back and runs Start() on everything. Both times to set-up an object make sense, so Unity gave us both, and a choice to use either or both (or none).

    It won;t matter which one you use unless you want to talk about another gameObject. That's why new Unity scripts have Start() and not Awake(). If you use myCatRB=myCat.GetComponenet<Rigidbody>(); in Start(), we know your cat object has been created along with it's rigidbody. We don''t know if your cat has run it's Start() yet, but that won't matter.

    In rare cases you need both. Suppose your cat has to create it's rigidbody. That's weird but could happen. So the intermediate-level advice is: use Awake() to set-up yourself. It happens before anyone will ever see you. Use Start() to do stuff using other objects. They will be safe since they did all of their required stuff in their Awake(). It's a little complicated, but not because of Unity. Starting-up any computer thinig is a little complicated.