Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
11 Jun 22 - 14 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 /
avatar image
0
Question by Unturned · Aug 10, 2015 at 12:34 PM · dictionarycstatic class

Object reference not set to an instance of an object

I am trying to make a short pokemon-inspired battlesystem, but I am having a bit of trouble; I keep getting the error message; "NullReferenceException: Object reference not set to an instance of an object Abilities.AddMove (System.String dictionaryKeyID) (at Assets/Scripts/Battle Moves/Abilities.cs:26) TextBoxContent.Awake () (at Assets/Scripts/UI/TextBoxContent.cs:30)"

I have been trying to clear this up for a few days now, but with no luck. Any help would be much appreciated!

The Abilities class: public class Abilities : MonoBehaviour {

     public List<Ability> abilities;
 
     //Add move to Pokemon's list of moves.
     public void AddMove(string dictionaryKeyID)
     {
         dictionaryKeyID = "WaterGun";
         // Code that checks you don't already have 4 moves, etc, etc
         Debug.Log ("Testing the dictionaryKeyID: " + dictionaryKeyID);
         // Add move - using its unique string in the dictionary.
 
         bool test = AbilityDatabaseScript.abilityDictionary [dictionaryKeyID];
         Debug.Log("Found dictionaryKeyID in dictionary: " + test);
 
         foreach (string key in AbilityDatabaseScript.abilityDictionary.Keys)
             Debug.Log ("Ability: " + key);
 
         //Debug.Log("list of abilities exists: " );
         abilities.Add(AbilityDatabaseScript.abilityDictionary[dictionaryKeyID]);
     }
 }

The AbilityDatabaseScript class:

 public static class AbilityDatabaseScript {
     public static Dictionary<string, Ability> abilityDictionary = new Dictionary<string, Ability>() {
         {"WaterGun", new Ability{_name = "Water Gun", _description = "It's a water gun.", _baseDamageAmount = 10
             }},
         {"Tackle", new Ability{_name = "Tackle", _description = "Tackle the opponent to the ground.", _baseDamageAmount = 10
             }},
         {"Ember", new Ability{_name = "Ember", _description = "Burn the motherfuckers.", _baseDamageAmount = 10
             }}
         
     };
 }
 

And the TextBoxContent class;

 public class TextBoxContent : MonoBehaviour {
 
     public Text descriptionText;
     public Text buttonText;
     public Button myButton;
     public GameObject Trainer; // get pokemonlist from this guy?
     public Pokemon fightingPokemon;
     public PokemonList pokeList;
 
     public int moveNumber;
     public string testString;
 
     // Use this for initialization
     void Awake () {
         pokeList = gameObject.GetComponent<PokemonList>();
         pokeList.AddPokemon ("Bulbasaur", 5, "1111");        //object ref
         pokeList.AddPokemon ("Squirtle", 5, "2222");    
         fightingPokemon = pokeList.pokemonList [0];
 
         testString = fightingPokemon.pokemonName;  // gets the right name
         fightingPokemon.AddMove ("Tackle");     // This is where the issue appears    
     }
 
     public void UpdateTexts (bool hovering) {
         if (hovering) {
             buttonText.color = Color.red;
             descriptionText.color = Color.red;
         } else {
             descriptionText.text = "";
             descriptionText.color = Color.clear;
         }
     }

     // Update is called once per frame
     void Update () {
 
     }
 }

At this point I'm just trying to get the textbox on a button to display the proper move-name, and another textbox to display the move-description.

I often get the error: "You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). " From other similar questions I take it that the issue is with my use of static classes.

Using Debug.Log I can see that it is capable of finding the ability from the static class AbilityDatabaseScript, but When I try to add the ability to the pokemon's list of abilities, I get an "Object reference not set to an instance of an object" error.

Just for reference, here are the pokemon scripts:

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;
 
 public class Pokemon : Abilities {
 
     public string pokemonName;
     public string regNumber;
 
     public int[] statIncreasesPerLevel;
     public float attack;
     public float spAttack;
     public float defense;
     public float spDefense;
     public float speed;
     public float accuracy;
     public int level; 
 }
 

PokemonList class:

 using UnityEngine;
 using System;
 using System.Reflection;
 using System.Collections;
 using System.Collections.Generic;
 
 public class PokemonList : MonoBehaviour {
 
     public List<Pokemon> pokemonList;
     public List<Pokemon> pokemonPcList;
 
     private string regNumber1;
     private string regNumber2;

     public void AddPokemon (string dictionaryName, int level, string regNumber) {
         Debug.Log("Pokemon found by keyName: " + PokemonDatabaseScript.pokemonDictionary [dictionaryName].pokemonName);
         bool test = PokemonDatabaseScript.pokemonDictionary [dictionaryName];
         Debug.Log("Found pokemon in dictionary: " + test);
         Pokemon caughtPokemon = PokemonDatabaseScript.pokemonDictionary[dictionaryName];
         caughtPokemon.level = level;
         caughtPokemon.regNumber = regNumber;
         // Code that checks you don't already have 6 pokemon, else send to bank, etc, etc          
         // Add pokemon - using its unique string name in the dictionary.
         pokemonList.Add(caughtPokemon);
     }
 
     public Pokemon ReturnPokemon(string dictionaryName) {
         return PokemonDatabaseScript.pokemonDictionary[dictionaryName];
     }
 
     public void SwitchPokemon () {
         //switch pokemon matching regNumber1 with pokemon matching regNumber2 in Pokemon List
     }
 }


static PokemonDatabaseScript class (containing the static dictionary):

 using UnityEngine;
 using System.Collections;
 using System.Collections.Generic;

 public static class PokemonDatabaseScript  {
     public static Dictionary<string, Pokemon> pokemonDictionary = new Dictionary<string, Pokemon>() {
         {"Bulbasaur", new Pokemon{pokemonName = "Bulbasaur", attack = 10, spAttack = 9, defense = 15, spDefense = 10, speed = 7, accuracy = 9
                 }},
         {"Squirtle", new Pokemon{pokemonName = "Squirtle", attack = 9, spAttack = 11, defense = 16, spDefense = 7, speed = 10, accuracy = 9
                 }},
         {"Charmander", new Pokemon{pokemonName = "Charmander", attack = 10, spAttack = 10, defense = 10, spDefense = 10, speed = 15, accuracy = 15
                  }}    
     };        
 }
 
 



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 allenallenallen · Aug 10, 2015 at 01:42 PM 0
Share

@Hellium, my bad.

3 Replies

· Add your reply
  • Sort: 
avatar image
1
Best Answer

Answer by Willyzekid · Aug 10, 2015 at 01:02 PM

You need to instantiate the 'abilities' variable somewhere in your Abilities class (a new List somewhere in a start function)

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 stepan-stulov · Aug 10, 2015 at 02:03 PM 0
Share

This field (by being public) is automatically instantiated for you by Unity, because the generic List is supported by Unity's serialization system. Re-instantiating it will cause loss of all the hand-injected abilities if there were any.

Update: pardon, what I said only holds true if the Ability is a serializable class. If not, I do not recommend declring a serialized field of a non-serializable class. In this case you indeed do need to manually instantiate the list and not rely on Unity.

avatar image
0

Answer by Unturned · Aug 10, 2015 at 01:38 PM

Willyzekid: Adding a start function and instantiating the abilities variable didn't work, but simply changing it to:

 public List<Ability> abilities = new List<Ability>(); 
 

in stead of

 public List<Ability> abilities;
  

fixed the problem.

Thanks to stepan.stulov for telling me about the awake function, I think that explains some of the other issues I've had previously :)

Comment
Add comment · Show 2 · 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 stepan-stulov · Aug 10, 2015 at 01:49 PM 0
Share

I'm surprised this solved the problem. Because Generic lists are included into Unity serialization supported classes. Any serialized field of type of List is going to be instantiated by Unity automatically for you. You don't need to instantiate public or serialized private fields of this type yourself. In fact doing so can cause double instantiation and furthermore loss of hand-injected filling of the list if such happened in the inspector. What version of Unity are you using? And are you 100% positive just this one fix solved the problem?

Try it yourself:

 public class Test : $$anonymous$$onoBehaviour
 {
     public List<float> myFloats;
     
     public void Start()
     {
         Debug.Log(string.Format("$$anonymous$$y floats has {0} elements", myFloats.Count.ToString()));
     }
 }

Now either (1) fill the list with some floats in the inspector or (2) don't. In case of (1) the log will get you the count, in case of (2) the log will get you zero. But no null-pointer exception.

In fact now I suspect that one of these abilities that was injected into the list, got deleted, so the list's reference was pointing to a non-existing object (null/none). In this case re-instantiating the list only hid the problem, not solved it.

Update: pardon, what I said only holds true if the Ability is a serializable class. If not, I do not recommend declring a serialized field of a non-serializable class. In this case you indeed do need to manually instantiate the list and not rely on Unity.

avatar image Unturned · Aug 10, 2015 at 05:03 PM 0
Share

I would try out your advice, but I'm not certain what you're trying to suggest? I haven't worked much with serializable fields, and I'm not sure what advantage this would give me.

avatar image
0

Answer by stepan-stulov · Aug 10, 2015 at 01:25 PM

You are referencing a list of externally injected game objects from within the Awake() method. This is too early, as it's not guaranteed that those referenced objects are there yet.

General rule of thumb: mess with own internals in the Awake() and with externals in the Start(). Dependencies are injected for all the scene game objects somewhere in between all Awake()'s and all Start()'s.

Comment
Add comment · 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

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

6 People are following this question.

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

Related Questions

Returning variables in a plugin 1 Answer

Change animation after double tapping arrow 0 Answers

Missing Materials on build 1 Answer

Maintain the parameters associated with a Object? 1 Answer

Dictionary in inspector 4 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