4

In my Unity 4.3 all work well, but after Upgrade to 5 I have a problem with GetComponent. To test a new deprecable GetComponent I have use the official tutorial

using UnityEngine;
using System.Collections;
public class test : MonoBehaviour {
public GameObject otherGameObject;
private AnotherScript anotherScript;
void Awake ()
{
    anotherScript = GetComponent<AnotherScript>();
}

void Update ()
{
    Debug.Log("The player's score is " + anotherScript.playerScore);
}
}

And the second script

 using UnityEngine;
 using System.Collections;
 public class AnotherScript : MonoBehaviour {
 public int playerScore = 9001;
 }

This is only for test,

i've used the same example of the unity tutorial https://unity3d.com/learn/tutorials/modules/beginner/scripting/getcomponent

After that I've associated the two object in the editor But the run report is:

NullReferenceException: Object reference not set to an instance of an object test.Update () (at Assets/test.cs:22)

in unity 4.3 work well.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • Try adding a constructor to the `AnotherScript` class like `public AnotherScript(){ playerScore = 9001;}` this also means that when the variable is declared you should remove the part where it is assigned a value – Alfie Goodacre Apr 14 '16 at 11:49
  • 1
    @AlfieGoodacre. No. **Never** use constructor in a Unity script that that derives from `MonoBehavior`. – Programmer Apr 14 '16 at 11:52
  • @Programmer sorry I am not the best with Unity, hence I didn't answer, `Start()` then maybe? :) – Alfie Goodacre Apr 14 '16 at 11:53
  • @AlfieGoodacre yes, that may work. – Programmer Apr 14 '16 at 11:55
  • Are you sure that both scripts are in the same GameObject? You could try to add Start method for AnotherScript and see if it even gets called. – FINDarkside Apr 14 '16 at 12:04
  • GetComponent used to search the whole scene in previous versions of unity. Now you have to have the second script attached to the same gameObject. However, I'd advise to always use references, or transfrom.GetComponent<>() in your case. – Nika Kasradze Apr 14 '16 at 12:07
  • hi @fabrizioofabrizio . I investigated and this question had been asked 917 times on this site, and 15412 times on answers.unity. Much like the "golden State Warriors", you have broken a record. – Fattie Apr 14 '16 at 13:20
  • 1
    @JoeBlow I have understood that but I would prefer not to delete it as it does not reflect negatively upon me, as it can not be downvoted. Not only this, but it would cause a lot of hassle for Programmer too, as his comments would no longer make sense – Alfie Goodacre Apr 14 '16 at 13:21
  • 1
    also, apart from the basic mistake. Nobody has mention a ***huge problem*** you have. Basically, you should never have a variable that is both "public" and you assign a "default" value to it (9001). it really leads to mass confusion. Please read this http://stackoverflow.com/a/35166004/294884 and vote it up. – Fattie Apr 14 '16 at 13:22
  • 1
    hi @AlfieGoodacre I agree that Mugi is pretty cool. I can assure you that **the best course of action is to delete your two first comments** up the top. (A) Programmer, who is exceptionally alert in general as well as being experienced on this site, will know to delete their comments. (Indeed, anyone using the site for more than 2 weeks would know that.) (B) Even in the extraordinary case that Programmer did not do that, the internet is better-off without the two misleading comments. There's a huge problem with misleading comments in the Unity *milieu*. You have a nice day now – Fattie Apr 14 '16 at 13:25

4 Answers4

4

You should try getting the reference in the Start method. Make sure that both test and AnotherScript scripts are attached to the-same GameObject in the Editor, then the code below should work.

using UnityEngine;
using System.Collections;

public class test: MonoBehaviour 
{
    public int playerScore;

    void Start()
    {
        anotherScript = gameObject.GetComponent<AnotherScript>();
    }

    void Update ()
    {
       Debug.Log("The player's score is " + anotherScript.playerScore);
    }
}

If both Scripts are not attached to the-same GameObject then use:

 anotherScript = GameObject.Find("Name of GameObject AnotherScript is Attched To").GetComponent<AnotherScript>();
Programmer
  • 121,791
  • 22
  • 236
  • 328
Alfie Goodacre
  • 2,753
  • 1
  • 13
  • 26
  • When I said do it in start, I meant `GetComponent();` in Start function instead of Awake. The -1 is not from me. Fixed it for you. – Programmer Apr 14 '16 at 12:14
  • @Programmer It should be in Awake though. And the current answer makes no sense, you combined those two scripts into one. – FINDarkside Apr 14 '16 at 12:19
  • @FINDarkside. No. It doesn't have to be done in the Awake. Assuming both Scripts are attached to the-same GameObject, this should work. – Programmer Apr 14 '16 at 12:19
  • @FINDarkside. I saw your comment and didn't want to reply because it just keeps going and it a not an **important** argument in this question. What you said depends on the project and the structure of your scripts. For example, If **ObjectA** depends on **ObjectB** to work, **ObjectB** should be initialized in the `Awake` function and **ObjectA** should be initialized in the `Start` function or you will get null error. – Programmer Apr 14 '16 at 18:31
  • @FINDarkside You will probably notice this when your project gets bigger with over 30 scripts talking to each other. Doing what I said above will usually fix it or you will have to manually do it in the **Script Execution Order** settings in the Editor. So it depends.... When you say "**It should be in Awake**", it is misleading and will make people make mistakes or won't be able to solve their null exception problems because they read online that variables should be initialized in the `Awake` function and not in the `Start` function. – Programmer Apr 14 '16 at 18:37
  • @Programmer You should initialize all public fields in Awake, so if some other script depends on the other script, it can use it in Start and except it to be initialized. That's probably the biggest reason why there even is Start and Awake.. But as you said this is irrelevant, but the thing is that moving GetComponent to Start will not change or solve anything. – FINDarkside Apr 14 '16 at 19:59
3

You need to use FindObjectOfType<AnotherScript>() if the scripts are not attached to the same GameObject.

FINDarkside
  • 2,102
  • 1
  • 18
  • 26
3

I believe this should be so:

public GameObject otherGameObject;


private AnotherScript anotherScript;


void Awake ()
{
    anotherScript = otherGameObject.GetComponent<AnotherScript>();

}

void Update ()
{
    Debug.Log("The player's score is " + anotherScript.playerScore);
}

}

And you should attach otherGameObject in the editor.

emrebaris
  • 59
  • 4
2

Are you sure that AnotherScript is also attached to the same Gameobject you test-script is attached to?

The GetComponent Method only looks for Components attached to GameObjects.

The easy way would for sure be to make anotherScript member public (so it´s exposed in the inspector) and drag´n´drop your script in there to get the reference.

Dahli
  • 51
  • 3