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

Unity 6中Scriptable Object事件系统重启编辑器后失效求助

基于Scriptable Object的事件系统重启Unity后失效问题排查与解决

问题描述

参照YouTube教程实现的Scriptable Object事件系统,初始运行正常,但重启Unity编辑器后监听器完全失效。复制带监听器的游戏对象可在当前会话恢复功能,但保存重启后问题复发。已尝试删除Libraries文件夹、重置偏好设置、重写脚本等操作,仅能暂时缓解。添加Debug.Log后确认事件已触发,但监听器的OnEventRaised方法未执行。当前使用Unity 6000.0.43f1,此前6000.0.39f1版本也存在相同问题。

相关代码

GameEventListener 脚本

using UnityEngine;
using UnityEngine.Events;

public class GameEventListener : Activation
{
    [SerializeField] GameEventAsset gameEvent;
    [SerializeField] UnityEvent onEventTriggered;

    public GameEventAsset GameEvent { get { return gameEvent; } set { gameEvent = value; } }
    public UnityEvent OnEventTriggered { get { return onEventTriggered; } set { onEventTriggered = value; } }

    private void OnEnable()
    {
        Debug.Log("OnEnable Event");
        gameEvent.AddListener(this);
    }

    private void OnDisable()
    {
        gameEvent.RemoveListener(this);
        onEventTriggered = null;
    }

    public void OnEventRaised()
    {
        Debug.Log("OnEventRaised");
        onEventTriggered.Invoke();
    }
}

GameEventAsset Scriptable Object 脚本

using System.Collections.Generic;
using UnityEngine;

[CreateAssetMenu(menuName = "ScriptableObjects/GameComponent/Event/This is GameDev SO Event System")]
public class GameEventAsset : ScriptableObject
{
    [SerializeField] List<GameEventListener> listeners = new List<GameEventListener>();
    public void AddListener(GameEventListener listener)
    {
        Debug.Log(listener);

        if (listener != listeners.Contains(listener))
        {
            Debug.Log(listener + " Is listener");

            listeners.Add(listener); 
        }
    }

    public void RemoveListener(GameEventListener listener)
    {
        listeners.Remove(listener);
    }

    public void TriggerEvent() 
    {
        Debug.Log(listeners.Count + " Trigger Event Start");

        for (int i = 0; i < listeners.Count; i++) 
        {
            Debug.Log(listeners[i] + " Trigger Event Engaged");

            listeners[i].OnEventRaised(); 
        }
    }
}

故障原因

  1. 序列化导致的无效引用:GameEventAsset中的listeners列表被标记为[SerializeField],Unity会序列化保存该列表的引用。但重启Unity后,场景中的监听器对象是新实例,原序列化的引用指向旧对象,导致调用OnEventRaised时无响应。
  2. AddListener逻辑错误:if (listener != listeners.Contains(listener))的判断逻辑完全错误——Contains返回布尔值,与listener对象比较永远为true,会导致重复添加监听器,甚至在引用无效时引发异常。
  3. OnDisable中的错误操作:OnDisable中执行onEventTriggered = null;会清空UnityEvent的绑定,重启后序列化的事件绑定丢失,导致即使监听器注册成功也无法触发回调。

解决方法

  1. 移除listeners的序列化标记
    修改GameEventAsset中的列表定义,避免Unity序列化运行时的监听器列表:

    List<GameEventListener> listeners = new List<GameEventListener>();
    
  2. 修复AddListener判断逻辑
    将错误的判断替换为正确的存在性检查:

    public void AddListener(GameEventListener listener)
    {
        Debug.Log(listener);
    
        if (!listeners.Contains(listener))
        {
            Debug.Log(listener + " Is listener");
            listeners.Add(listener); 
        }
    }
    
  3. 删除OnDisable中的onEventTriggered置空操作
    保留监听器移除逻辑即可,防止清空序列化的UnityEvent绑定:

    private void OnDisable()
    {
        if (gameEvent != null)
        {
            gameEvent.RemoveListener(this);
        }
        // 移除 onEventTriggered = null; 这一行
    }
    
  4. 添加空引用检查与遍历优化

    • 在GameEventListener.OnEnable中添加空引用判断,避免空指针异常:
      private void OnEnable()
      {
          Debug.Log("OnEnable Event");
          if (gameEvent != null)
          {
              gameEvent.AddListener(this);
          }
      }
      
    • 在GameEventAsset.TriggerEvent中复制列表后遍历,防止遍历中列表变更引发异常:
      public void TriggerEvent() 
      {
          Debug.Log(listeners.Count + " Trigger Event Start");
          // 复制列表避免遍历过程中列表修改导致的异常
          var tempListeners = new List<GameEventListener>(listeners);
          foreach (var listener in tempListeners)
          {
              if (listener != null)
              {
                  Debug.Log(listener + " Trigger Event Engaged");
                  listener.OnEventRaised(); 
              }
          }
      }
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 16:21:03