Unity中脚本多次测试后抛出NullReferenceException问题求助
Unity空引用异常问题排查与修复
问题背景
C#基础薄弱,学校项目包含两个Unity脚本:Game_Handler负责游戏核心逻辑,Game_Set_Handler管理题目字典。项目初始运行正常,但测试6-7次后会触发空引用异常;复制脚本修改类名后可正常运行几次,之后仍会出现相同问题。
相关代码
Game_Set_Handler 完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.Linq; using UnityEngine.UI; using System.Threading.Tasks; using System.Diagnostics; using Random = System.Random; public class Game_Set_Handler : MonoBehaviour { public class Set { public string? Question { get; set; } public int StartingPoints { get; set; } public string Answer1 { get; set; } public string Answer2 { get; set; } public string Answer3 { get; set; } public string? Answer4 { get; set; } public string? Answer5 { get; set; } } public Dictionary<int, Set> Sets; public void Handler() { Sets = new Dictionary<int, Set>() { {1,new Set { Question="sports to play outside", StartingPoints=250, Answer1 = "football", Answer2 = "baseball", Answer3 = "basketball", Answer4 = "soccer", Answer5 = "golf"}}, {2,new Set { Question="board games", StartingPoints=375, Answer1 = "chess", Answer2 = "checkers", Answer3 = "monopoly",Answer4 = "battleship",Answer5 = "mancala"}}, {3,new Set { Question="famous religions", StartingPoints=400, Answer1 = "christianity", Answer2 = "islam", Answer3 = "judaism",Answer4 = "buddhism",Answer5 = "hinduism"}}, {4,new Set { Question="types of bread in the USA", StartingPoints=225, Answer1 = "banana", Answer2 = "sourdough", Answer3 = "white",Answer4 = "wheat",Answer5 = "pumpkin"}}, {5,new Set { Question="car brands in the USA", StartingPoints=100, Answer1 = "ford", Answer2 = "chevrolet", Answer3 = "toyota",Answer4 = "honda",Answer5 = "volkswagen"}}, }; } void Start() { Handler(); } public int Get_Question() { int value = new Random().Next(0, Sets.Count + 1); return value; } }
Game_Handler 关联代码
var dictionary = Parent.GetComponent<Game_Set_Handler>().Sets; //Parent是Canvas,两个脚本都挂载其上 int dict_key = Parent.GetComponent<Game_Set_Handler>().Get_Question();
触发的错误信息
NullReferenceException: Object reference not set to an instance of an object Game_Set_Handler.Get_Question () (at Assets/Scripts/Game_Set_Handler.cs:53) Game_Handler.Start_Game () (at Assets/Scripts/Game_Handler.cs:60) Game_Handler.Start () (at Assets/Scripts/Game_Handler.cs:121)
问题根源与修复方案
核心问题点
Sets字典可能未初始化:Game_Set_Handler的Start方法执行时机晚于Game_Handler的Start时,Sets仍为null,调用Get_Question时访问Sets.Count会触发空引用。- 随机数生成逻辑错误:
Random.Next(0, Sets.Count +1)会生成0到5的随机数,但字典的键是1-5,生成0时后续访问字典会出错;且每次调用Get_Question都新建Random实例,短时间内多次调用会生成重复随机数,甚至因系统时钟精度问题导致异常。 - 重复调用
GetComponent:Game_Handler中每次访问都调用GetComponent,不仅效率低,还可能因对象状态变化获取到null。
具体修复步骤
提前初始化字典并调整初始化时机:
将Sets声明改为直接初始化,并将字典初始化移到Awake方法(Awake比Start执行更早,确保Game_Handler访问时字典已就绪):public Dictionary<int, Set> Sets = new Dictionary<int, Set>(); void Awake() { Handler(); }优化随机数生成逻辑:
声明静态Random实例避免重复创建,同时调整随机数范围为1到Sets.Count,确保生成的键一定存在于字典中:private static Random _random = new Random(); public int Get_Question() { // 双重保险,确保字典已初始化 if (Sets == null || Sets.Count == 0) { Handler(); } // 生成1到Sets.Count之间的随机数(包含两端) return _random.Next(1, Sets.Count + 1); }优化
Game_Handler中的组件访问逻辑:
缓存Game_Set_Handler实例,增加空值检查,避免重复调用GetComponent:var setHandler = Parent.GetComponent<Game_Set_Handler>(); if (setHandler == null) { Debug.LogError("Canvas上未挂载Game_Set_Handler组件"); return; } var dictionary = setHandler.Sets; int dict_key = setHandler.Get_Question();
内容的提问来源于stack exchange,提问作者Issaiah Teneyck
相关产品推荐
相关产品推荐

