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 就解决了它。
所以,我对场景中的单一行为脚本(我们称之为脚本 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 就解决了它。