Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Desperate on a small error , please help :<

Discussion in 'Scripting' started by N3rKMinD, Jan 24, 2011.

  1. N3rKMinD

    N3rKMinD

    Joined:
    Jan 9, 2011
    Posts:
    41
    Been on the same error for 6 days /madface

    The source of my error come from

    GetSkill((int)SkillName.Armor).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Strength), 1.5f));

    SkillName Armor is the second skill of my Skill list

    http://i55.tinypic.com/2w4ctwz.jpg
    Heres the full error :

    Code (csharp):
    1.  
    2. NullReferenceException: Object reference not set to an instance of an object
    3. BaseCharacter.SetupVitalModifiers () (at Assets/Script/Character Classes/BaseCharacter.cs:92)
    4. BaseCharacter.SetupVitals () (at Assets/Script/Character Classes/BaseCharacter.cs:65)
    5. BaseCharacter.Awake () (at Assets/Script/Character Classes/BaseCharacter.cs:24)
    6. CharacterGenerator.Start () (at Assets/Script/Character Classes/CharacterGenerator.cs:14)
    7.  
    Edit : Posted the full script below

    Send me a tell on Mick_doyon@hotmail.com if you need the scripts .
     
    Last edited: Jan 24, 2011
  2. TheRaider

    TheRaider

    Joined:
    Dec 5, 2010
    Posts:
    2,249
    maybe posting the at least first line of code which has the problem might help.
     
  3. callahan.44

    callahan.44

    Joined:
    Jan 9, 2010
    Posts:
    694
    3 nested functions in 1 line?
    Maybe break it down into some temporary variables so you can see which is Null referencing with Debug.Log?
     
  4. N3rKMinD

    N3rKMinD

    Joined:
    Jan 9, 2011
    Posts:
    41
    Thanks for the awnser guys, really apreciate it ^_^

    Heres the script
    Code (csharp):
    1.  
    2. using UnityEngine;
    3. using System.Collections;
    4. using System;               // acess enum
    5.  
    6. public class BaseCharacter : MonoBehaviour {
    7.     private string _name;
    8.     private int _level;
    9.     private uint _freexp;
    10.    
    11.     private Attribute[] _primaryAttribute;
    12.     private Vital[] _vital;
    13.     private Skill[] _skill;
    14.    
    15.     public void Awake() {
    16.         _name = string.Empty;
    17.         _level = 0;
    18.         _freexp = 0;
    19.        
    20.         _primaryAttribute = new Attribute [Enum.GetValues(typeof(AttributeName)).Length];
    21.         _vital = new Vital [Enum.GetValues(typeof(VitalName)).Length];
    22.         _skill = new Skill [Enum.GetValues(typeof(SkillName)).Length];
    23.        
    24.         SetupPrimaryAttributes();
    25.         SetupVitals();
    26.         SetupSkills();
    27.     }
    28.    
    29.         public string Name {
    30.             get{ return _name; }
    31.             set{ _name = value; }
    32.     }
    33.         public int Level {
    34.             get{ return _level; }
    35.             set{ _level = value; }
    36.     }
    37.         public uint Freexp {
    38.             get{ return _freexp; }
    39.             set{ _freexp = value; }
    40.     }
    41.     /// <summary>
    42.     /// Setups the primary attributes.
    43.     /// </summary>
    44.  
    45.     public void Addxp(uint xp) {
    46.         _freexp += xp;
    47.         CalculateLevel();
    48.     }
    49.    
    50.     //take avg of all players skill and assign that as player level
    51.     public void CalculateLevel() {
    52.        
    53.     }
    54.        
    55.         private void SetupPrimaryAttributes(){
    56.             for(int cnt = 0; cnt < _primaryAttribute.Length; cnt++) {
    57.                 _primaryAttribute[cnt] = new Attribute();
    58.            
    59.         }
    60.     }
    61.         private void SetupVitals(){
    62.              
    63.             for(int cnt = 0; cnt < _vital.Length; cnt++) {
    64.                 _vital[cnt] = new Vital();
    65.            
    66.         SetupVitalModifiers();
    67.            
    68.         }
    69. }
    70.         private void SetupSkills(){
    71.             for(int cnt = 0; cnt < _skill.Length; cnt++) {
    72.                 _skill[cnt] = new Skill();
    73.                
    74.         SetupSkillModifiers();
    75.     }
    76.   }
    77.     public Attribute GetPrimaryAttribute(int index){
    78.         return _primaryAttribute[index];
    79.     }
    80.     public Vital GetVital(int index){
    81.         return _vital[index];
    82.     }      
    83.     public Skill GetSkill(int index){
    84.         return _skill[index];
    85.     }
    86.     // ===================================================================================================== //
    87.       private void SetupVitalModifiers() {
    88.         //HP
    89.             GetVital((int)VitalName.Health).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Stamina), 5f));
    90.        
    91.         //Chakra
    92.             GetVital((int)VitalName.Chakra).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Intelect), 5f));
    93.     }
    94.     // ===================================================================================================== //
    95.     private void SetupSkillModifiers() {
    96.         // Attack power
    97.             GetSkill((int)SkillName.Attack_Power).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Strength), 2.5f));
    98.             GetSkill((int)SkillName.Attack_Power).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Agility), 0.2f));
    99.        
    100.         // Armor
    101.             GetSkill((int)SkillName.Armor).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Strength), 1.5f));
    102.        
    103.         // Ranged power
    104.             GetSkill((int)SkillName.Ranged_Power).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Agility), 2f));
    105.             GetSkill((int)SkillName.Ranged_Power).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Strength), 1f));
    106.        
    107.         // Magic offence
    108.             GetSkill((int)SkillName.Magic_Offence).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Intelect), 3.5f));
    109.        
    110.         // Movement_Speed
    111.             GetSkill((int)SkillName.Movement_Speed).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Agility), .33f));
    112.        
    113.         // Attack_Speed
    114.             GetSkill((int)SkillName.Attack_Speed).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Agility), .5f));
    115.        
    116.         // Chakra_Regen
    117.             GetSkill((int)SkillName.Chakra_Regen).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Spirit), 1f));
    118.             GetSkill((int)SkillName.Chakra_Regen).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Intelect), .2f));
    119.        
    120.         // Hitpoints_Regen
    121.             GetSkill((int)SkillName.Hitpoints_Regen).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Spirit), 1f));
    122.        
    123.         }
    124.     // ===================================================================================================== //
    125.     public void StatUpdate() {
    126.         for(int cnt = 0; cnt < _vital.Length; cnt++)
    127.             _vital[cnt].Update();
    128.        
    129.         for(int cnt = 0; cnt < _skill.Length; cnt++)
    130.             _skill[cnt].Update();
    131.     }
    132. }
    133.  
     
  5. N3rKMinD

    N3rKMinD

    Joined:
    Jan 9, 2011
    Posts:
    41
    shameless self bump.
     
  6. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    First off, gotta reduce some of your code duplication to make it a bit more readable. Firstly, all that duplicate casting should be done within your methods:
    Code (csharp):
    1.  
    2. public Attribute GetPrimaryAttribute(AttributeName attributeName)
    3. {
    4.     return _primaryAttribute[(int)attributeName];
    5. }
    6.  
    7. public Vital GetVital(VitalName vital)
    8. {
    9.     return _vital[(int)vital];
    10. }      
    11.  
    12. public Skill GetSkill(SkillName skill)
    13. {
    14.     return _skill[(int)skill];
    15. }
    16.  
    Which turns your usage of them from this:

    GetVital((int)VitalName.Health).AddModifier(new ModifyingAttribute(GetPrimaryAttribute((int)AttributeName.Stamina), 5f));

    to:

    GetVital(VitalName.Health).AddModifier(new ModifyingAttribute(GetPrimaryAttribute(AttributeName.Stamina), 5f));


    Next, start breaking down the nested calls:

    Code (csharp):
    1.  
    2. GetVital(VitalName.Health).AddModifier(new ModifyingAttribute(GetPrimaryAttribute(AttributeName.Stamina), 5f));
    3.  
    4. //changes to
    5.  
    6. Vital vital = GetVital(VitalName.Health);
    7. Attribute staminaPrimaryAttribute = GetPrimaryAttribute(AttributeName.Stamina);
    8. ModifyingAttribute healthStaminaModifier = new ModifyingAttribute(staminaPrimaryAttribute, 5f);
    9. vital.AddModifier(staminaPrimaryAttribute);
    10.  
    Then you can start adding Debug.Logs to see where the null reference is:

    Code (csharp):
    1.  
    2. Vital vital = GetVital(VitalName.Health);
    3. Debug.Log("vital null? " + (vital == null));
    4. Attribute staminaPrimaryAttribute = GetPrimaryAttribute(AttributeName.Stamina);
    5. Debug.Log("staminaPrimaryAttribute null? " + (staminaPrimaryAttribute == null));
    6. ModifyingAttribute healthStaminaModifier = new ModifyingAttribute(staminaPrimaryAttribute, 5f);
    7. Debug.Log("healthStaminaModifier null? " + (healthStaminaModifier == null));
    8. vital.AddModifier(staminaPrimaryAttribute);
    9.  

    You could also do something like this to reduce duplication:

    Code (csharp):
    1.  
    2. private void AddSkillModifier(SkillName skillName, AttributeName primaryAttributeName, float modifier)
    3. {
    4.     Skill skill = GetSkill(skillName);
    5.     Attribute primaryAttribute = GetPrimaryAttribute(primaryAttributeName);
    6.     ModifyingAttribute modifyingAttribute = new ModifyingAttribute(primaryAttribute, modifier);
    7.     skill.AddModifier(modifyingAttribute);
    8. }
    9.  
    10. private void SetupSkillModifiers()
    11. {
    12.     // Attack power
    13.     AddSkillModifier(Skillname.Attack_Power, AttributeName.Strength, 2.5f);
    14.     AddSkillModifier(SkillName.Attack_Power, AttributeName.Agility, 0.2f);
    15.    
    16.     // Armor
    17.     AddSkillModifier(SkillName.Armor, AttributeName.Strength, 1.5f);
    18.  
    19.     //and so on
    20. }
    21.  
    So you can see how making minor tweaks like this can really help make your code much more readable and easier to change/debug.



    FYI, "intellect" has two letter "L" in it.



    EDIT: also, personally, I wouldn't use arrays or lists for the enumerations. They might be the most efficient to use those arrays, but I'm a stickler for type-safe intent-driven code. For example, those enums can be given explicit values (beyond 0 through N) that skip numbers, doing so would break all this code.

    To that end, I'd rather see:
    Code (csharp):
    1.  
    2. using System.Collections.Generic;
    3.  
    4. public class BaseCharacter : MonoBehaviour
    5. {
    6.     private Dictionary<AttributeName, Attribute> _primaryAttributes = new Dictionary<AttributeName, Attribute>();
    7.     private Dictionary<VitalName, Vital> _vitals = new Dictionary<VitalName, Vital>();
    8.     private Dictionary<SkillName, Skill> _skills = new Dictionary<SkillName, Skill>();
    9.    
    10.     public void Awake()
    11.     {  
    12.         SetupPrimaryAttributes();
    13.         SetupVitals();
    14.         SetupSkills();
    15.     }
    16.  
    17.     private void SetupPrimaryAttributes()
    18.     {
    19.         foreach(AttributeName attributeName in Enum.GetValues(typeof(AttributeName)))
    20.         {
    21.             _primaryAttributes.Add(attributeName, new Attribute());
    22.         }
    23.     }
    24.  
    25.     private void SetupVitals()
    26.     {
    27.         foreach(VitalName vitalName in Enum.GetValues(typeof(VitalName)))
    28.         {
    29.             _vitals.Add(vitalName, new Vital());
    30.         }
    31.            
    32.         SetupVitalModifiers();
    33.     }
    34.  
    35.  
    36.     private void SetupSkills()
    37.     {
    38.         foreach(SkillName skillName in Enum.GetValues(typeof(SkillName)))
    39.         {
    40.             _skills.Add(skillName, new Skill());
    41.         }
    42.         SetupSkillModifiers();
    43.     }
    44.  
    45.     public Attribute GetPrimaryAttribute(AttributeName attributeName)
    46.     {
    47.         return _primaryAttributes[attributeName];
    48.     }
    49.  
    50.     public Vital GetVital(VitalName vital)
    51.     {
    52.         return _vitals[vital];
    53.     }      
    54.  
    55.     public Skill GetSkill(SkillName skill)
    56.     {
    57.         return _skills[skill];
    58.     }
    59. }
    60.  

    Coincidentally, I think I found the source of your bug. In the "SetupVitals" method, you made the "SetupVitalModifiers" call within the foreach statement; I think your intent is to have it outside. I already moved it outside the foreach in my code posted above.


    EDIT: just to clarify, you initialize the first Vital, say "Health", but then you run the SetupVitalModifiers method which then also tries to alter the "Chakra" vital which has not yet been set. So first you need to initialize them all, then set them up.
     
    Last edited: Jan 24, 2011
  7. callahan.44

    callahan.44

    Joined:
    Jan 9, 2010
    Posts:
    694
    Does AddModifier( ModifyingAttribute?) add to a List<T> or something similar? is it initialised when you assign it the new index/node?

    public List<Node> nodes = new List<Node>();
    node = new Node()
    nodes.Add(node);

    If it's not that, check the functions that are returning a class reference.


    btw I'm lazy.. I always add a new enum called Max to the end of my lists rather than use Enum.GetValues(typeof(Blah)).Length lol
     
  8. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Given the stack trace, I don't think the error resides in the "AddModifier" method.
     
  9. callahan.44

    callahan.44

    Joined:
    Jan 9, 2010
    Posts:
    694
    @fizixman I saw functions like DisplayVitals() were spitting out null reference errors too, so something isn't initialised internally there.
    btw nice job cleaning up the code :)
     
  10. N3rKMinD

    N3rKMinD

    Joined:
    Jan 9, 2011
    Posts:
    41
    your a hero.
     
  11. Chris-Sinclair

    Chris-Sinclair

    Joined:
    Jun 14, 2010
    Posts:
    1,326
    Naw, just made the mistake of downing a big cup of coffee at 12:30am. Glad I could help!