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

DialogueEvent无法将DialogueEventListener注册到监听器列表问题求助

对话系统事件注册问题排查与解决

我正在开发带事件机制的对话系统,现有DialogueEvent和DialogueEventListener类代码如下。将DialogueEventListener挂载到GameObject后,其引用的DialogueEvent ScriptableObject(SO)未成功注册监听器,手动添加也无效,把注册逻辑移到Awake里同样没用。现在因为空引用错误(NRE)导致对话系统无法运行。

现有代码

DialogueEvent 类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Assets.Scripts.Dialogue
{
    [CreateAssetMenu(menuName = "ScriptableObjects/GameEvent/DialogueEvent")]
    public class DialogueEvent : ScriptableObject
    {
        public List<DialogueEventListener> listeners = new List<DialogueEventListener>();
       
        // Raise event through different methods

        public void Raise(Component sender, object data)
        {
            for(int i = 0; i < listeners.Count; i++)
            {
                listeners[i].OnEventRaised(sender, data);
            }
        }

        // Manage Listeners

        public void RegisterListener(DialogueEventListener dialogueEventListener)
        {
            if(!listeners.Contains(dialogueEventListener))
            {
                listeners.Add(dialogueEventListener);
            }
        }

        public void UnregisterListener(DialogueEventListener dialogueEventListener)
        {
            if(listeners.Contains(dialogueEventListener))
            {
                listeners.Remove(dialogueEventListener);
            }
        }
    }
}

DialogueEventListener 类

using System.Collections;
using UnityEngine;
using UnityEngine.Events;

namespace Assets.Scripts.Dialogue
{
    public class DialogueEventListener : MonoBehaviour
    {
        // EVENT VARIABLES
        [SerializeField]
        private DialogueEvent dialogueEvent;
        [SerializeField]
        private CustomDialogueEvent response;
        public DialogueEvent DialogueEvent
        {
            get => dialogueEvent;
            set => dialogueEvent = value;
        }
        public CustomDialogueEvent Response
        {
            get => response;
            set => response = value;
        }
        
        // FUNCTIONS
        private void OnEnable()
        {
            dialogueEvent.RegisterListener(this);
        }

        private void OnDisable()
        {
            dialogueEvent.UnregisterListener(this);
        }

        public void OnEventRaised(Component sender, object data)
        {
            response.Invoke(sender, data);
        }

    }
}

解决步骤

  • 检查SO引用有效性:在Inspector面板中确认DialogueEventListener组件的dialogueEvent字段已正确拖入对应的DialogueEvent ScriptableObject实例,未留空。
  • 添加空引用防护:修改OnEnable和OnDisable方法,避免空引用错误中断注册流程:
    private void OnEnable()
    {
        if (dialogueEvent != null)
        {
            dialogueEvent.RegisterListener(this);
        }
    }
    
    private void OnDisable()
    {
        if (dialogueEvent != null)
        {
            dialogueEvent.UnregisterListener(this);
        }
    }
    
  • 验证注册逻辑:在DialogueEvent的RegisterListener方法中添加日志,确认注册流程是否执行:
    public void RegisterListener(DialogueEventListener dialogueEventListener)
    {
        if (!listeners.Contains(dialogueEventListener))
        {
            listeners.Add(dialogueEventListener);
            Debug.Log($"监听器 {dialogueEventListener.gameObject.name} 已注册到事件 {name}");
        }
        else
        {
            Debug.Log($"监听器 {dialogueEventListener.gameObject.name} 已存在于事件 {name} 的监听列表中");
        }
    }
    
  • 重新创建SO实例:若原DialogueEvent SO存在异常,尝试创建新的SO实例并重新赋值给DialogueEventListener。
  • 检查响应事件引用:确认DialogueEventListener的response字段(CustomDialogueEvent)也已正确赋值,避免后续触发事件时出现空引用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 05:23:10