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 Alengthyname · Jun 19, 2016 at 05:03 AM · errornullreferenceexceptionforeach

Null Reference in script after having called other class without a null reference

Hello,

I'm in the process of creating the backbone for a training system for a tactic driven game. I've set up two means of increasing stats/attributes: doing jobs when the turn ends, and being actively trained. I have an "End Turn" button that is attached to a UIManager script (see below) that sets the doJobs bool to true and does the jobs as I'd expect. This is accomplished by clicking a button with the OnPointerDown() function that holds a value, and then clicking on a character in the roster to assign the job.

I've set up the training ID the same as the job ID, with buttons having an OnPointerDown() call to pass the ID to a global variable, and a pairing for that to the character ID in the update function of the roster. When trying to do training however, I'm getting a NullRef.

In the past I've solved this by just making sure everything is assigned properly in the inspector, but I'm calling Roster more than once in this script and it's only throwing it for training.

the jobs/training is done here:

 public class JobDoer:Monobehavior
 {
 bool doJobs = false;
 bool doTraining = false;
 public Roster charRost;
 public void JobsOnTurnEnd()
     {
     if (doJobs == true)          
             foreach (BaseCharacter b in charRost.characterRoster)
             {                
                 if (b.jobID == 0) 
                 {
                     JobRest(b);
                 }
           }
     }
     public void Training()
        {
       if (doTraining == true)           
         foreach (BaseCharacter b in charRost.characterRoster)  //null reference gets thrown here
         {
             if (b.trainID == 1) 
             {
                 TrainStrength(b);
             }
       }
     }
   }

I genuinely have no idea why this is happening and have spent the bulk of the last 2 days tracing back through my code over and over again, with no results. I'm able to get the training ID set to the student ID (checked it through debugging), but when I do a training trigger it throws the above error. If anyone could help I would greatly appreciate it.

[EDIT]: I tried using the doJobs bool and the end turn button to do the training, and it works that way; so it seems the issue is related to the trigger.

The above may not be enough information to go on, so below are trimmed versions of scripts that have some sort of interaction with the above.

 public class CharacterData
 {   
 public int characterID;
 //attributes
 public int strength = 0;    
  //job/training stuff
  public int trainID = 0;
  public int jobID = 0;
  public bool isStudent = false;
 }

which is used as the data for:

 public class BaseCharacter: CharacterData
 {
 }

I then use the BaseCharacter class to create an array of characters:

 public class Roster :MonoBehaviour
 {
  
  public void CreateRoster()  //creates character data
 {      
     characterRoster = new BaseCharacter[characters];
     for (int i = 0; i < characters; i++)
     {
         characterRoster[i] = new BaseCharacter();
         characterRoster[i].characterID = i; //generates ID
         //then I generate the rest of the attributes by a random number generator adding to each and decrementing from a pool 
   }
   public void PopulateRosterPanel(int start, int last) 
 {
     //here I set up a roster of prefab panels between some bounds
  }
   public int SelectStudent() //allows for selecting a character
 {
     foreach (BaseCharacter b in characterRoster)
     {           
        bool der = //is the mouse over the character's panel?
         bool canSelect = true;
         if (der && canSelect)
         {
             if (Input.GetMouseButtonDown(0)) //on left click, select one
             {
                 selectedID =b.characterID; 
                 jobCharacterID.IDPair(b);   //pairs the job id with the character                 
             }
         }
     }      
   return selectedID;
 }
   void Update()
  {      
  studentTrain.TrainID(characterRoster[SelectedVar.StudentID]);      
  }
  }

The job assignment stuff:

  public class Jobs : MonoBehaviour, IPointerDownHandler{    
  public int jobID;

 public void OnPointerDown(PointerEventData eventData) //default ID = 0
 {
     if (this.gameObject.name == "RestButton")
     {
         jobID = 0;
     }
 }
 public int JobAssign(int JID) //character or characterID and JobID 
 {
     JobVar.JobID = JID;        
     return JobVar.JobID;
 }
 
 public void IDPair(BaseCharacter b)
 {       
         b.jobID = JobVar.JobID;        
     if (b.jobID == 5)
     {
         SelectedVar.StudentID = b.characterID;      
         b.isStudent = true; 
     }
 }    

The end turn job triggers:

 public class UIManager : MonoBehaviour 
 {
 public  JobDoer turnJobs;
 public void EndTurn()
  {  
     turnJobs.doJobs = true;
     turnJobs.JobsOnTurnEnd();
 }

Training stuff:

  public class StudentTraining : MonoBehaviour , IPointerDownHandler
  {
  public void OnPointerDown(PointerEventData eventData)
   {           
       if (this.gameObject.name == "TrainStrengthButton")
       {
           trainID = 1;       
       }  
       TrainAssign(trainID);
     }
   public int TrainAssign(int TID) 
   {       
       JobVar.TrainID = TID;
       return JobVar.TrainID;
   }
   public void TrainID(BaseCharacter b)
   {
       b.trainID = JobVar.TrainID;
   }
  }

and my training trigger (which I've tried attached both to the instantiated student prefab and to a non-instantiated button in the student panel) is :

  public class ToggleTraining : MonoBehaviour 
    {

   public JobDoer jobDo;
   public void Toggle()
   {
      jobDo.doTraining = true;
       jobDo.Training();
    }
    }

where I've got 3 global variables for student, job, and training id:

 public static class JobVar
 {
   static int _jobID;

 public static int JobID
 {
     get { return _jobID; }
     set { _jobID = value; }
 }

 static int _trainID;
 public static int TrainID
 {
     get { return _trainID; }
     set { _trainID = value; }
 }

 }
 public static class SelectedVar
 {
 static int _studentID;
 public static int StudentID
 {
     get { return _studentID; }
     set { _studentID = value; }
 }

}

Comment
Add comment · Show 1
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 phxvyper · Jun 19, 2016 at 07:44 AM 0
Share

You really should use some Debug.Log()'ing to deter$$anonymous$$e where the scope of your issue is. Posting your entire code base is usually a bad idea, especially since it discourages other Unity developers from reading your entire post and helping you.

Anyways, do Debug.Log(charRost.gameObject.Name); before your foreach statement on line 20 in your JobDoer object. What happens when you run that code?

0 Replies

· Add your reply
  • Sort: 

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

4 People are following this question.

avatar image avatar image avatar image avatar image

Related Questions

Null Reference Exception Error 1 Answer

Bugs on my C# Scripts? 0 Answers

Null Reference Exception when changing material shader 0 Answers

NullReferenceException, Script Error 1 Answer

There's an issue with this script I can't find 0 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