You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

问题根源与修复方案

核心问题点

  1. Sets字典可能未初始化:Game_Set_Handler的Start方法执行时机晚于Game_Handler的Start时,Sets仍为null,调用Get_Question时访问Sets.Count会触发空引用。
  2. 随机数生成逻辑错误:Random.Next(0, Sets.Count +1)会生成0到5的随机数,但字典的键是1-5,生成0时后续访问字典会出错;且每次调用Get_Question都新建Random实例,短时间内多次调用会生成重复随机数,甚至因系统时钟精度问题导致异常。
  3. 重复调用GetComponent:Game_Handler中每次访问都调用GetComponent,不仅效率低,还可能因对象状态变化获取到null。

具体修复步骤

  1. 提前初始化字典并调整初始化时机:
    将Sets声明改为直接初始化,并将字典初始化移到Awake方法(Awake比Start执行更早,确保Game_Handler访问时字典已就绪):

    public Dictionary<int, Set> Sets = new Dictionary<int, Set>();
    
    void Awake()
    {
        Handler();
    }
    
  2. 优化随机数生成逻辑:
    声明静态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);
    }
    
  3. 优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:00:07