Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

AddLIstener returning null reference

Discussion in 'Scripting' started by Emolk, Feb 20, 2020.

  1. Emolk

    Emolk

    Joined:
    Feb 11, 2014
    Posts:
    241
    Hi, i'm making dev tools for my game. I'm using a custom UI package with a custom dropdown class.

    I'm aiming to have a dropdown menu of all the enemies in the game (dynamically added from resources.loadall) so i can select any and then spawn them into the game.

    This is all working, the dropdown menu works fine as shown below.

    The issue i'm having is when i try to add a listener to the OnItemSelection, i get an Null Reference Exception. Happens on line 28. I want to be able to pass enemy (a prefab) into the listener, so when an item is selected, the enemy i can spawn into the game changes.

    I'm not sure if i'm using listeners correctly as i have never used them before.

    When i run this code:

    Code (CSharp):
    1. print(item.OnItemSelection);
    I get 'Null' in the console.

    Thanks.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using Michsky.UI.ModernUIPack;
    4. using UnityEngine;
    5.  
    6. public class DevEnemySpawn : MonoBehaviour
    7. {
    8.     public GameObject[] enemyPrefabs;
    9.     public CustomDropdown enemyDropdown;
    10.  
    11.     void Start(){
    12.         enemyPrefabs = Resources.LoadAll<GameObject>("Enemies");
    13.  
    14.         enemyDropdown.dropdownItems = new List<CustomDropdown.Item>();
    15.  
    16.         foreach (var enemy in enemyPrefabs)
    17.         {
    18.             CustomDropdown.Item item = new CustomDropdown.Item();
    19.  
    20.             item.itemName = enemy.name;
    21.  
    22.             if(enemy.GetComponent<SpriteRenderer>())
    23.                 item.itemIcon = enemy.GetComponent<SpriteRenderer>().sprite;
    24.             else
    25.                 item.itemIcon = enemy.GetComponentInChildren<SpriteRenderer>().sprite;
    26.             item.enemy = enemy;
    27.  
    28.             item.OnItemSelection.AddListener(delegate{SelectEnemy(enemy);});
    29.  
    30.             enemyDropdown.dropdownItems.Add(item);
    31.         }
    32.  
    33.         enemyDropdown.SetupDropdown();
    34.  
    35.         // enemyDropdown.UpdateValues();
    36.     }
    37.  
    38.     public void SelectEnemy(GameObject enemy){
    39.  
    40.     }
    41. }
    42.  

    Dropdown menu


     
  2. Josiah_Kunz

    Josiah_Kunz

    Joined:
    Jun 8, 2017
    Posts:
    9
    Hi! I have had a similar problem with adding listeners in loops. In that case, you're adding a variable ("enemy") to the listener that gets overwritten several times. Instead, you need to allocate new memory each you add a listener. For example, you could replace:

    Code (CSharp):
    1. foreach (var enemy in enemyPrefabs)
    2.         {
    with

    Code (CSharp):
    1. for(int i=0; i<enemyPrefabs.Length; i++)
    2.         {
    3.             var enemy = enemyPrefabs [i];
     
  3. Antistone

    Antistone

    Joined:
    Feb 22, 2014
    Posts:
    2,835
    Josiah_Kunz makes a valid observation, but that wouldn't cause a NullReferenceException.

    Presumably either "item" or "item.OnItemSelection" is null. If "print(item.OnItemSelection)" prints "null" rather than throwing an exception, then OnItemSelection is null.

    You haven't included the source code for CustomDropdown.Item, so I'm not sure what the type of OnItemSelection is or how it's supposed to be initialized, but that's probably where your main problem will be.

    By the way, your thread title is wrong; "throwing a NullReferenceException" and "returning null" mean totally different things.