Unity WebGL Gameobject 从某处禁用

Unity WebGL Gameobject disabled from somewhere

所以,我对场景中的单一行为脚本(我们称之为脚本 A)进行了更新 运行。此更新会触发一个事件,因此其他非单一行为脚本在需要更新某些内容时可以收听此事件。但是,在应用程序启动时,它会在脚本 A 上运行更新一小段时间,但一段时间后它会随机停止调用脚本 A 上的更新。

所以我开始在标准的单一行为函数中放置一些调试,例如唤醒、启动、禁用、启用等。结果是对象在某个地方被禁用,而我没有在任何地方使用或调用它。此问题仅发生在 WebGL 上。在编辑器中永远不会调用 OnDisable 事件并且更新保持 运行 正常。

我尝试了各种修复,就像到处都是调试日志一样,我尝试调试堆栈跟踪以找出调用此 OnDisable 的原因,据说这不会显示在 WebGL 控制台中。它只是说:StackTrace:

public class UpdateManager : MonoBehaviour
{
    private static UpdateManager _instance;
    public static UpdateManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<UpdateManager>();

                if (_instance == null)
                {
                    GameObject updateManager = new GameObject("UpdateManager");
                    _instance = updateManager.AddComponent<UpdateManager>();
                }
            }

            return _instance;
        }
    }

    public delegate void OnUpdateEvent();
    public event OnUpdateEvent OnUpdate;

    private void Awake()
    {
        Debug.Log("UpdateManager: Awake!"); 
    }     

    private void Start()
    {
        Debug.Log("UpdateManager: Start!"); 
    }

    private void OnEnable()
    {
        Debug.Log("UpdateManager: OnEnable!"); 
    }

    private void OnDisable()
    {
        Debug.Log("UpdateManager: OnDisable!, Stacktrace: " + UnityEngine.StackTraceUtility.ExtractStackTrace()); 
    }

    private void Update()
    {
        Debug.Log("UpdateManager: Update!");
        OnUpdate?.Invoke();
    }

我想知道是什么禁用了这个对象,因为我不知道。这里要注意的是,它只在开始时被禁用一次,在我再次启用它之后,它在剩余时间内运行良好。

我调用此脚本的唯一地方是静态 class 某处:

    private static void initializeRefreshCycle(int expiresIn)
    {
        if (expiresIn > 0)
        {
            if (_refreshRoutine != null)
            {
                CoroutineManager.Instance.Stop(_refreshRoutine);
                _refreshRoutine = null;
            }

            DateTime expirationDateTime = DateTime.Now;
            _refreshTime = expirationDateTime.AddSeconds(expiresIn * 0.85f);
            Debug.Log(string.Format("<< API TOKEN WILL BE AUTOMATICALLY REFRESHED IN {0} SECONDS >>", expiresIn * 0.85f));

            UpdateManager.Instance.OnUpdate += OnUpdateEarly;
        }
    }

然后是真正监听调用的函数:

   public static void OnUpdateEarly()
    {
        if (!HasAlmostExpired) return;

        SSOCommunicator.RefreshToken(_refresh);
        UpdateManager.Instance.OnUpdate -= OnUpdateEarly;
    }

好像是第一次停在某处,再次到达订阅后,剩余时间运行正常。

我发现这是一个垃圾回收问题。因为我总是调用 UpdateManager.Instance 来调用一个函数,所以我从来没有硬引用过那个实例。所以它以某种方式在开始时仅在 WebGL 上被破坏了。我通过在脚本唤醒时保留硬引用来解决它。所以只要有一个简单的 _updatamanager = Updatemanager.Instance 就解决了它。