Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
0
Question by luigiwagner · May 03, 2017 at 07:51 AM · scripting problem2d game2d-platformervariablesscriptingbasics

Variable from another script isn´t updating

So, my question is actually pretty simple.

I have a script that destroys the obstacles in the game (DestroyerScript) that is as follows:

 public class DestroyerScript : MonoBehaviour {
 
     public int destroyed;
 
     void Start()
     {
         destroyed = 0;
     }
     
     void OnTriggerEnter2D(Collider2D other)
     {
         if(other.tag == "Player")
         {
             Debug.Break();
             return;
         }
 
         if (other.gameObject.transform.parent == true) //is child of another object
         {
             destroyed++;
             Destroy(other.gameObject.transform.parent.gameObject); //destroys the parent 
             Debug.Log("Destroyed " + destroyed.ToString() + " obstacles");
         }
         else //is not child of another object -> essentially the condition that always plays in this case
         {
             if(destroyed == 5)
             {
                 destroyed = 0;
             }
             else
             {
                 destroyed++;
             }
 
             Debug.Log("Destroyed " + destroyed.ToString() + " obstacles");
             Destroy(other.gameObject); //destroys obstacle that collided
         }
     }
 }
 

I have the variable destroyed that is public (I know the correct thing to do is to manipulate it through a function, but this is only for a matter of testing) and I increment it every time a obstacle is destroyed (when five are destroyed, I reset the value of said variable to 0).

Now I have another script that I use to instantiate the obstacles (InstaForeground).

What I want to do in this second script is use the destroyed variable from the first script as the decider to whether I should or not instantiate the obstacles, which I´m trying to do as follows:

 public class InstaForeground : MonoBehaviour {
      .
      . 
      .
      .
     void Start()
     {
         Spawn(); //here I´m just instantiating five obstacles as a starter
     }
 
     void Update()
     {
         if(destroyerScript.GetComponent<DestroyerScript>().destroyed == 5)
         {
             Debug.Log("FIVE WERE DESTROYED");
             Spawn();
         }
     }
 
     void Spawn()
     {
            //Irrelevant for now
     }
     .
     .
     .
     .
 }


But apparently, like this, destroyed isn´t being changed as it runs here (as it should according to the other script which updates it [since the Debug.Log isn´t being printed, it shows that it doesn´t enter the if condition which I established].

Why isn´t the variable using it´s values according to the DestroyerScript ?

Remember that destroyed is declared as public there.

OBS.: The console in pointing the following error:

NullReferenceException: Object reference not set to an instance of an object InstaForeground.Update () (at Assets/Scripts/InstaForeground.cs:60)

l-> It is referring to the if statement line:

if(destroyerScript.GetComponent().destroyed == 5)

Any help will be hugely appreciated.

Comment
Add comment · Show 2
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · May 03, 2017 at 08:47 AM 0
Share

I moved the question to the Help Room as we had covered NullReferenceException problems several times by now.

avatar image luigiwagner · May 04, 2017 at 02:49 AM 0
Share

$$anonymous$$y main goal with what I´m trying to do is to make it in a way that I can only spawn a new batch of obstacles every time 5 past obstacles have been destroyed.

Nothing too wild, just a matter o controlling the pace in which the obstacles are instantiated in the scene, ins$$anonymous$$d of it being all at once (specially because they are supposed spawn infinitely until the player dies).

@Bunny83 @OfficialCoatsee

3 Replies

· Add your reply
  • Sort: 
avatar image
0

Answer by Bunny83 · May 03, 2017 at 08:42 AM

If you get a null reference exception on that line that means that either:

  • the destroyerScript variable is null, doesn't reference anything.

  • the object referenced in the destroyerScript variable doesn't have a DestroyerScript attached.

Those are the only two things that could cause a null reference exception. What exactly is "destroyerScript"? How does it get it's value in the first place? Do you assign something in the inspector or do you assign it manually inside a script?

edit
In the code you posted in the comment below you wrote:

 //[ ... ]
 private DestroyerScript destroyerScript;
 
 void Start()
 {
     DestroyerScript destroyerScript = GetComponent<DestroyerScript>();
     // [ ... ]

Here you first declare a member variable inside of your "InstaForeground" class. However inside Start you declare another local variable also named "destroyerScript". Setting this local variable won't change / set the member variable of your script.

Instead you don't want to declare a new local variable but simply assign something to the member variable

 //[ ... ]
 private DestroyerScript destroyerScript;
 
 void Start()
 {
     destroyerScript = GetComponent<DestroyerScript>();
     // [ ... ]

Note the difference between the two code snippets.

However keep in mind that calling GetComponent<DestroyerScript>() the way you did is equal to gameObject.GetComponent<DestroyerScript>(). So this only works when both your "InstaForeground" script as well as your "DestroyerScript" are attached to the very same GameObject. GetComponent will return null if there isn't a component of the specified type attached to this gameobject.


Additional note:
An exception in a program is an unexpected situation in your program that will forcefully terminate your method at the point the exception occurs. You're actually lucky that Unity actually catches the exception at a higher level. In a "normal" C# application an unhandled exception would result in the termination / crash of your application.

If you see in the console that any kind of exception is thrown you have to find the reason for that. Any other debugging actions are pointless at this moment. An exception breaks the normal program flow, so it's possible that important initialization code had not a chance to run which might cause tons of other errors. When you have a problem (runtime exception or compiler error) you always start debugging with the first error you encounter.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image luigiwagner · May 04, 2017 at 02:32 AM 0
Share

Regarding the first point: how can I be sure to be referring the object properly?

Is it something like this?

 DestroyerScript destroyerScript = GetComponent<DestroyerScript>();

If so, where should I write it?

destroyerScript is a script attached to game object that destroys the obstacles in the game upon collision. The destroyed variable I assign through the script as it shows in the destroyerScript I posted on the original question.

avatar image EdwinChua luigiwagner · May 04, 2017 at 02:36 AM 0
Share

@luigiwagner Please see my comment to your original question above. It describes how you should approach this problem.

avatar image Bunny83 · May 04, 2017 at 07:38 AM 0
Share

I've updated my answer.

avatar image
0

Answer by OfficialCoatsee · May 03, 2017 at 08:53 AM

I think, and I may be wrong... But?

 if(destroyed == 5)  {
          destroyed = 0; //maybe this is getting reset to early?
 } else {
          destroyed++;
 }

Because you are doing a check, right? From the other script?

 if(destroyerScript.GetComponent<DestroyerScript>().destroyed == 5) {
      Debug.Log("FIVE WERE DESTROYED");
      Spawn();
 }

So why don't you do the reset, in the check?

     if(destroyerScript.GetComponent<DestroyerScript>().destroyed == 5) {
          Debug.Log("FIVE WERE DESTROYED");
          destroyerScript.GetComponent<DestroyerScript>().destroyed = 0;
          Spawn();
     }

Also, I am assuming you are calling the 'destroyerScript' properly? Meaning that the InstaForeground script knows what the DestroyerScript is attached to (impossible to tell, considering I don't know if you have shown the full code for the InstaForeground script).

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image luigiwagner · May 04, 2017 at 02:42 AM 0
Share

I tried doing the reseting in the check, but it didn´t work :/

If you think it may help, here follows the InstaForeground Script:

 public class InstaForeground : $$anonymous$$onoBehaviour {
 
     public int maxPlataforms = 5;
     public GameObject[] plataform;
     public float horizontal$$anonymous$$in = 7.5f;
     public float horizontal$$anonymous$$ax = 14f;
     public float vertical$$anonymous$$in = -6f;
     public float vertical$$anonymous$$ax = 6f;
 
     private Vector2 originPosition;
 
     public int prefab_num;
 
     private DestroyerScript destroyerScript;
 
 
     void Start()
     {
         DestroyerScript destroyerScript = GetComponent<DestroyerScript>();
 
         Spawn(); //this spawns the first batch of 5 obstacles
     }
 
 
     void Update()
     {
         if(destroyerScript.GetComponent<DestroyerScript>().destroyed == 5)
         {
             Debug.Log("FIVE WERE DESTROYED");
             destroyerScript.GetComponent<DestroyerScript>().destroyed = 0;
             Spawn();
         }
         if (destroyerScript.GetComponent<DestroyerScript>().destroyed < 5)
         {
             destroyerScript.GetComponent<DestroyerScript>().destroyed = destroyerScript.GetComponent<DestroyerScript>().destroyed + 1;
         }
 
     }
 
     void Spawn()
     {
         int fr = 0;
 
         Debug.Log("Entered Spawn()");
         for (int i = 0; i < maxPlataforms; i++)
         {
             prefab_num = Random.Range(0, 1);
             Vector2 randomPosition = originPosition + new Vector2(Random.Range(horizontal$$anonymous$$in, horizontal$$anonymous$$ax), Random.Range(vertical$$anonymous$$in, vertical$$anonymous$$ax));
             if (fr == 0)
             {
                 Instantiate(plataform[1], randomPosition, Quaternion.identity);
                 fr = 1;
             }
             else
             {
                 Instantiate(plataform[0], randomPosition, Quaternion.identity);
                 fr = 0;
             }
             originPosition = randomPosition;
         } 
         
     }
 }
 
avatar image
0

Answer by EdwinChua · May 03, 2017 at 08:33 AM

@luigiwagner The NullReferenceException means that the script was unable to find the correct component. Please ensure both scripts are attached to the same object, or assign the gameobject to a public variable.

i.e. destroyerScript in your example could be used like this:

 public class InstaForeground : MonoBehaviour {
 
       public GameObject destroyerScript; // click and drag from inspector to assign. Ensure the object assigned has the DestroyerScript component added
 
  
      void Update()
      {
          if(destroyerScript.GetComponent<DestroyerScript>().destroyed == 5)
          {
              Debug.Log("FIVE WERE DESTROYED");
              Spawn();
          }
      }
  }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image luigiwagner · May 04, 2017 at 02:59 AM 0
Share

Incredible, man. It worked like a charm.

Thank you so much for the help, it actually enlighted me in some important things regarding Unity!

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

7 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Main Menu Help! 3 Answers

Object reference not set to an instance of an object 0 Answers

Broken Jump Physics 0 Answers

My character won't stop crouching, they dont stop crouchin 2 Answers

Display Variable with UI Text 2 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges