Search Unity

NullReferenceException when none of variables should be null.

Discussion in 'Scripting' started by xNihel, Oct 16, 2017.

  1. xNihel

    xNihel

    Joined:
    Oct 9, 2017
    Posts:
    8
    So uh.. We have a problem with one line of code we don't know how to fix(second code, on try catch).
    It tells us that one of variables is null. It shouldn't be and i can't find any mistake here.
    Here's the message we get:
    So if anyone would be that kind to give me a hint what to do i would reallly appreciate it.
    Ask questions if u don't understand my way of thinking in code, i will definetely answer.

    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6.  
    7.  
    8. public class TurnScript // : MonoBehaviour
    9. {
    10.     public enum Action // Teoretyczne enum powinien być poza klasą ale wsadziłem go tutaj by inne klasy też mogły go wykorzystać.
    11.     { // Jak wszystkie klasy będą bazować na tym samym enumie to będzie łatwiej to ogarnąć.
    12.         Info,
    13.         Move,
    14.         Guard,
    15.         Attack,
    16.         Throw,
    17.         Pickup,
    18.         Processing
    19.     }
    20.  
    21.     public ActionInfo AII;
    22.     public ActionMove AM;
    23.     public Weapon AG;
    24.     public Weapon AA;
    25.     public Weapon AT;
    26.     public ActionPickup AP;
    27.  
    28.     public bool turnTime; //True - kiedy można wykonać ruch, False - wykonywanie akcji
    29.  
    30.     public void doTurn(Action action, Vector3 position, Vector3 clickpoint1, Vector3 clickPoint2)
    31.     {
    32.         turnTime = false; //Przed odtworzeniem ustawiwamy blokadę przycisków.
    33.         AM.MoveLogic(clickpoint1, position); //Na początku zawsze musi być wykonany jakiś ruch.
    34.         switch (action)
    35.         {
    36.             case Action.Info:
    37.                 //Tool Tips, Pause, ext. Nie będziemy tego na tą chwilę rozwijać. Może to kiedyś wykorzystamy choć niesądze.
    38.                 //   AII.InfoLogic();
    39.                 break;
    40.             case Action.Attack:
    41.                 //Damage step, assigning attackers and taking actions.
    42.                 AA.AttackLogic();
    43.                 break;
    44.             case Action.Guard:
    45.                 //Guard from attack and advantages.
    46.                 AG.GuardLogic();
    47.                 break;
    48.             case Action.Move:
    49.                 //Move logic and anything pertaining to movement actions with characters.
    50.                 AM.MoveLogic(clickPoint2, clickpoint1);
    51.                 break;
    52.             case Action.Throw:
    53.                 //Weapon throw, some weapon can't be throw
    54.                 AT.ThrowLogic();
    55.                 break;
    56.             case Action.Pickup:
    57.                 //Interactions with Dropped weapons
    58.                 //   AP.PickupLogic();
    59.                 break;
    60.             default:
    61.                 break;
    62.         }
    63.         turnTime = true; //Po odtworzeniu odblokujemy przyciski
    64.     }
    65.     public bool TurnTime
    66.     {
    67.         get
    68.         {
    69.             return turnTime;
    70.         }
    71.  
    72.         set
    73.         {
    74.             turnTime = value;
    75.         }
    76.     }
    77. }
    78.  
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Character : MonoBehaviour {
    7.  
    8.     /*
    9.      *  UWAGA !!!!.
    10.      *  Przed wszystkim musimy zwiększyć liczbę zmienntych do zapamiętania. To będzie główny cel tej klasy.
    11.      *  To ta klasa ma zapamiętać stany, siłę, możliwości, wektory poruszania, spadania itp...
    12.      *  Pozostałe klasy mają mieć po prostu funkcje takie na jaki cel wskazuje nazwa tej klasy.
    13.      *  Czyli Charakter ma tobić nam za swoistą bazę danych :)
    14.      *
    15.     */
    16.  
    17.     public float speed = 5f;
    18.    // Collider character;
    19.     public bool condition = true; // Stan w jakim jest character true(normalny)/false(ogłuszony)
    20.     public bool onTheGround = true; // Niektóre akcje wymagają bycia na ziemi
    21.     private bool isDead; //Tego chyba nie muszę tłumaczyć :D ~ M
    22.  
    23.     public Vector3 clickPoint1;
    24.     public Vector3 clickPoint2;
    25.  
    26.     TurnScript turn = new TurnScript();
    27.     public TurnScript.Action action = TurnScript.Action.Info; //To jest jak coś obiekt, nie INT. Żeby ktoś nie pomylił z C++;
    28.  
    29.     //public Transform GroundCheck1; // Put the prefab of the ground here
    30.     //public LayerMask groundLayer; // Insert the layer here.
    31.  
    32.     void Start()
    33.     {
    34.         turn.turnTime = true;
    35.         //turn = GetComponent<TurnScript>();
    36.         condition = true;
    37.         clickPoint1 = transform.position;
    38.         clickPoint2 = transform.position;
    39.         action = TurnScript.Action.Info;
    40.     }
    41.  
    42.     void Update()
    43.     {
    44.         if (turn.turnTime) //Sprawdzamy czas i czy możemy coś kliknąć. To ma blokować zmianę akcji podczas wykonywania.
    45.         {
    46.             if (action != TurnScript.Action.Move && Input.GetMouseButtonDown(0))
    47.             {
    48.                 clickPoint1 =  Input.mousePosition;
    49.                 Debug.Log(clickPoint1);
    50.             }
    51.             checkAction();
    52.             if (action == TurnScript.Action.Move && Input.GetMouseButtonDown(0))
    53.             {
    54.                 clickPoint2 = Input.mousePosition;
    55.                 Debug.Log(clickPoint2);
    56.             }
    57.             if (Input.GetButtonDown("space"))
    58.             {
    59.                 try
    60.                 {  
    61.                     turn.doTurn(action, transform.position, clickPoint1, clickPoint2);
    62.                 } catch (System.NullReferenceException ex)
    63.                 {
    64.                     Debug.Log("Mam dobrą i złą wiadomość. " +
    65.                         "Dobra: try/catch działa fajnie. " +
    66.                         "Zła: WCIĄŻ CZEPIA SIĘ O NULLA");
    67.                     Debug.Log(ex);
    68.                 }
    69.             }  
    70.         }
    71.     }
    72.  
     
    Last edited: Oct 16, 2017
  2. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Check the Turn script, line 32 (doTurn method).

    And never catch a NullReferenceException, but i think you just did this for debugging purposes...
     
  3. xNihel

    xNihel

    Joined:
    Oct 9, 2017
    Posts:
    8
    Yeah i did it for debugging purposes.
    I uploaded two same codes accidentaly, fixed now.
    I don't really get it why 32 line in turn script is wrong.
     
  4. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    Looks like the AM variable of type ActionMove is null.
     
    xNihel likes this.
  5. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    To catch this kind of error earlier on, do something like this:

    Code (csharp):
    1.  
    2. private void Awake()
    3. {
    4.   Debug.Assert(AM != null);
    5.   Debug.Assert(AG != null);
    6.   Debug.Assert(AA != null);
    7. //...etc...
    8. }
    9.  
    And pay attention to your console window. :D
     
    xNihel likes this.
  6. xNihel

    xNihel

    Joined:
    Oct 9, 2017
    Posts:
    8
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6.  
    7.  
    8. public class TurnScript : MonoBehaviour
    9. {
    10.     public enum Action // Teoretyczne enum powinien być poza klasą ale wsadziłem go tutaj by inne klasy też mogły go wykorzystać.
    11.     { // Jak wszystkie klasy będą bazować na tym samym enumie to będzie łatwiej to ogarnąć.
    12.         Info,
    13.         Move,
    14.         Guard,
    15.         Attack,
    16.         Throw,
    17.         Pickup,
    18.         Processing
    19.     }
    20.  
    21.     public ActionInfo AII;
    22.     public ActionMove AM;
    23.     public Weapon W;
    24.     public ActionPickup AP;
    25.  
    26.     public bool turnTime; //True - kiedy można wykonać ruch, False - wykonywanie akcji
    27.  
    28.     void Awake()
    29.     {
    30.         AM = GetComponent<ActionMove>();
    31.         W = GetComponent<Weapon>();
    32.         Debug.Assert(AM != null);
    33.         Debug.Assert(W != null);
    34.     }
    35.  
    36.     public void doTurn(Action action, Vector3 position, Vector3 clickpoint1, Vector3 clickPoint2)
    37.     {
    38.         turnTime = false; //Przed odtworzeniem ustawiwamy blokadę przycisków.
    39.         AM.MoveLogic(clickpoint1, position); //Na początku zawsze musi być wykonany jakiś ruch.
    40.         switch (action)
    41.         {
    42.             case Action.Info:
    43.                 //Tool Tips, Pause, ext. Nie będziemy tego na tą chwilę rozwijać. Może to kiedyś wykorzystamy choć niesądze.
    44.                 //   AII.InfoLogic();
    45.                 break;
    46.             case Action.Attack:
    47.                 //Damage step, assigning attackers and taking actions.
    48.                 W.AttackLogic();
    49.                 break;
    50.             case Action.Guard:
    51.                 //Guard from attack and advantages.
    52.                 W.GuardLogic();
    53.                 break;
    54.             case Action.Move:
    55.                 //Move logic and anything pertaining to movement actions with characters.
    56.                 AM.MoveLogic(clickPoint2, clickpoint1);
    57.                 break;
    58.             case Action.Throw:
    59.                 //Weapon throw, some weapon can't be throw
    60.                 W.ThrowLogic();
    61.                 break;
    62.             case Action.Pickup:
    63.                 //Interactions with Dropped weapons
    64.                 //   AP.PickupLogic();
    65.                 break;
    66.             default:
    67.                 break;
    68.         }
    69.         turnTime = true; //Po odtworzeniu odblokujemy przyciski
    70.     }
    71.  
    72.     public bool TurnTime
    73.     {
    74.         get
    75.         {
    76.             return turnTime;
    77.         }
    78.  
    79.         set
    80.         {
    81.             turnTime = value;
    82.         }
    83.     }
    84. }
    85.  
    Code (csharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5.  
    6. public class Character : MonoBehaviour {
    7.  
    8.     /*
    9.      *  UWAGA !!!!.
    10.      *  Przed wszystkim musimy zwiększyć liczbę zmienntych do zapamiętania. To będzie główny cel tej klasy.
    11.      *  To ta klasa ma zapamiętać stany, siłę, możliwości, wektory poruszania, spadania itp...
    12.      *  Pozostałe klasy mają mieć po prostu funkcje takie na jaki cel wskazuje nazwa tej klasy.
    13.      *  Czyli Charakter ma tobić nam za swoistą bazę danych :)
    14.      *
    15.     */
    16.  
    17.     public float speed = 5f;
    18.     public bool condition = true; // Stan w jakim jest character true(normalny)/false(ogłuszony)
    19.     public bool onTheGround = true; // Niektóre akcje wymagają bycia na ziemi
    20.     private bool isDead;
    21.     public bool turn;
    22.     public Vector3 clickPoint1;
    23.     public Vector3 clickPoint2;
    24.  
    25.     public TurnScript turnScript;
    26.     public TurnScript.Action action;
    27.     public ActionInfo AII;
    28.     public ActionMove AM;
    29.     public Weapon W;
    30.     public ActionPickup AP;
    31.     //public Transform GroundCheck1; // Put the prefab of the ground here
    32.     //public LayerMask groundLayer; // Insert the layer here.
    33.  
    34.     void Start()
    35.     {
    36.         condition = true;
    37.         clickPoint1 = transform.position;
    38.         clickPoint2 = transform.position;
    39.     }
    40.     private void Awake()
    41.     {
    42.         turnScript = GetComponent<TurnScript>();
    43.     }
    44.  
    45.     void Update()
    46.     {
    47.         if (turnScript.turnTime) //Sprawdzamy czas i czy możemy coś kliknąć. To ma blokować zmianę akcji podczas wykonywania.
    48.         {
    49.             if (action != TurnScript.Action.Move && Input.GetMouseButtonDown(0))
    50.             {
    51.                 clickPoint1 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    52.                 Debug.Log(clickPoint1);
    53.             }
    54.             checkAction(action);
    55.             if (action == TurnScript.Action.Move && Input.GetMouseButtonDown(0))
    56.             {
    57.                 clickPoint2 = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    58.                 Debug.Log(clickPoint2);
    59.             }
    60.             if (Input.GetButtonDown("space"))
    61.             {
    62.              
    63.             }  
    64.         }
    65.     }
    66.  
    67.     //void checkOnTheGround()
    68.     //{
    69.     //    onTheGround = Physics2D.OverlapCircle(GroundCheck1.position, 0.15f, groundLayer);
    70.     //    // checks if you are within 0.15 position in the Y of the ground
    71.     //}
    72.  
    73.     void checkAction(TurnScript.Action action) //Nie mamy rozwijanego menu więc tymczasowo przypisałem do klawiszy
    74.     {
    75.         if (Input.GetButtonDown("z"))
    76.         {
    77.             action = TurnScript.Action.Attack;
    78.             Debug.Log("Wybrano atak");
    79.         }
    80.         else if (Input.GetButtonDown("x") && onTheGround) //Blok oczywiście możemy wykonać tylko na ziemi. Tylko nie jestem pewien czy będziemy to sprawdzać w tym miejscu.
    81.         {
    82.             action = TurnScript.Action.Guard;
    83.             Debug.Log("Wybrano obrone");
    84.         }
    85.         else if (Input.GetButtonDown("c") && onTheGround)
    86.         {
    87.             action = TurnScript.Action.Move;
    88.             Debug.Log("Wybrano ruch");
    89.         }
    90.  
    91.     }
    92.     void checkIsDead()
    93.     {
    94.         if (isDead)
    95.         {
    96.         //    Destroy(character.gameObject);
    97.         }
    98.     }
    99.  
    100.     public bool IsDead
    101.     {
    102.         get
    103.         {
    104.             return isDead;
    105.         }
    106.  
    107.         set
    108.         {
    109.             isDead = value;
    110.         }
    111.     }
    112.  
    113. }
    114.  
    Now i have same problem with turnScript.turntime. It says it's null but when i try to change value it doesn't work.
    I tried changing value both in TurnScript and in Character. I tried making object in Character and changing it's value to true or false. None of these work :/.
     
  7. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Sorry, did you mean to say turnScript.turnTime is not null?
     
  8. xNihel

    xNihel

    Joined:
    Oct 9, 2017
    Posts:
    8
    no, it says it's null and i don't know how to make it = true for example.
     
  9. BlackPete

    BlackPete

    Joined:
    Nov 16, 2016
    Posts:
    970
    Well then if turnScript is null, you won't be able to access turnTime. You need to assign an instance to turnScript first.
     
  10. xNihel

    xNihel

    Joined:
    Oct 9, 2017
    Posts:
    8
    turnScript = GetComponent<TurnScript>();
    won't do?
     
  11. Suddoha

    Suddoha

    Joined:
    Nov 9, 2013
    Posts:
    2,824
    It will - given that there's a component of that type attached to the object.
    If not, you'll get "null" back. (actually you'll still get a faked TurnScript in the editor - but it'll make the null-test evaluate to true).

    You can also add one programmatically using 'AddComponent'. Or you enforce such a component by using the RequireComponentAttribute.
     
    xNihel likes this.
  12. xNihel

    xNihel

    Joined:
    Oct 9, 2017
    Posts:
    8
    Oh so that's how it works. Thanks, you were really helpful. I don't have any nulls now.