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

使用AR Foundation开发AR游戏遇EventManager空引用异常求助

问题描述

我正在使用AR Foundation开发一款AR游戏,运行时先出现UIManager.Update()中的NullReferenceException: Object reference not set to an instance of an object错误,通过在场景中引用对象解决后,又出现EventManager.TriggerEvent方法中的同类型空引用异常,以下是EventManager的相关代码:

private static EventManager eventManager;

public static EventManager instance
{
    get
    {
        if (!eventManager)
        {
            eventManager = FindObjectOfType(typeof(EventManager)) as EventManager;

            if (!eventManager)
            {
                Debug.LogError("There needs to be one active EventManger script on a GameObject in your scene.");
            }
            else
            {
                eventManager.Init();
            }
        }
        return eventManager;
    }
}

void Init()
{
    if (eventDictionary == null)
    {
        eventDictionary = new Dictionary<string, Action<Dictionary<string, object>>>();
    }
}

public static void StartListening(string eventName, Action<Dictionary<string, object>> listener)
{
    Action<Dictionary<string, object>> thisEvent = null;

    if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    {
        // Add the called function to the action
        thisEvent += listener;
        // Renew the dictionary with the action
        instance.eventDictionary[eventName] = thisEvent;
    }
    else
    {
        thisEvent += listener;
        instance.eventDictionary.Add(eventName, thisEvent);
    }
}

public static void StopListening(string eventName, Action<Dictionary<string, object>> listener)
{
    if (eventManager == null) return;
    Action<Dictionary<string, object>> thisEvent = null;
    if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    {
        thisEvent -= listener;
        instance.eventDictionary[eventName] = thisEvent;
    }
}

public static void TriggerEvent(string eventName, Dictionary<string, object> message)
{
    Action<Dictionary<string, object>> thisEvent = null;
    if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    {
        thisEvent.Invoke(message);
    }
}
解决办法

1. 修复TriggerEvent中的空引用

空引用的核心原因是:当某个事件的所有监听器都被移除后,字典中该事件对应的Action会变成null,此时调用thisEvent.Invoke(message)就会触发异常。

修改TriggerEvent方法,使用空条件运算符(?.)确保只有在thisEvent不为空时才调用Invoke:

public static void TriggerEvent(string eventName, Dictionary<string, object> message)
{
    Action<Dictionary<string, object>> thisEvent = null;
    if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    {
        thisEvent?.Invoke(message); // 仅当thisEvent非空时执行调用
    }
}

2. 清理字典中的空事件条目

为了避免字典中留存null的Action,修改StopListening方法,当移除最后一个监听器后,直接将该事件从字典中删除:

public static void StopListening(string eventName, Action<Dictionary<string, object>> listener)
{
    if (eventManager == null) return;
    Action<Dictionary<string, object>> thisEvent = null;
    if (instance.eventDictionary.TryGetValue(eventName, out thisEvent))
    {
        thisEvent -= listener;
        if (thisEvent == null)
        {
            instance.eventDictionary.Remove(eventName); // 移除空事件条目
        }
        else
        {
            instance.eventDictionary[eventName] = thisEvent;
        }
    }
}

3. 额外检查事项

  • 确保场景中存在且仅存在一个挂载了EventManager脚本的激活状态GameObject(单例模式要求)。
  • 检查调用TriggerEvent时传入的message参数是否为null(如果你的监听器依赖该参数非空,需提前判空或确保传入有效值)。

内容的提问来源于stack exchange,提问作者safae

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 11:23:13