Unity中Catch块内GameObject无法激活问题求助
网络检测面板激活失败问题排查
需求说明
尝试检测设备是否联网,无网络时激活显示“无网络连接”的面板。已将该面板拖入Inspector面板,挂载脚本的GameObject在层级面板中处于激活状态。
代码实现
public GameObject NoInternetConnectionPanel; private void Start() { //Check Internet Connection InvokeRepeating("CheckInternetConnection", 0f, 1f); } private void CheckInternetConnection() { var request = WebRequest.Create("http://google.com"); request.Method = "HEAD"; request.BeginGetResponse(result => { try { using (var response = request.EndGetResponse(result) as HttpWebResponse) { if (response.StatusCode == HttpStatusCode.OK) { Debug.Log("Internet connection available"); } /*else { Debug.Log("No internet connection"); }*/ } } catch (WebException ex) { Debug.Log("No internet connection"); NoInternetConnectionPanel.SetActive(true); } }, null); StartCoroutine(WaitAndCheck()); } private IEnumerator WaitAndCheck() { yield return new WaitForSeconds(1f); }
问题现象
控制台能正常输出“No internet connection”日志,但
NoInternetConnectionPanel.SetActive(true)无法激活面板,请问问题原因是什么?
问题原因分析
- UI操作线程错误:
BeginGetResponse的回调函数运行在后台线程,而Unity所有的UI组件操作(包括SetActive)必须在主线程执行,后台线程直接调用UI API不会生效,这是核心问题。 - 逻辑冗余导致请求堆积:已经通过
InvokeRepeating每秒触发一次检测,却在方法内部又启动了一个等待1秒的协程WaitAndCheck,完全多余,还会导致短时间内堆积大量未完成的网络请求,干扰正常逻辑。 - 未处理状态重复切换:即使线程问题解决,重复调用
SetActive(true)也可能因为面板状态未做判断,出现无意义的重复操作,但这不是当前激活失败的直接原因。
修复方案(推荐)
使用Unity官方的UnityWebRequest配合协程实现,所有操作都在主线程执行,同时优化检测逻辑:
using UnityEngine; using UnityEngine.Networking; using System.Collections; public class NetworkChecker : MonoBehaviour { public GameObject NoInternetConnectionPanel; private bool isPanelActive = false; private void Start() { // 调整检测间隔为5秒,避免频繁请求消耗资源 InvokeRepeating(nameof(CheckInternetConnection), 0f, 5f); } private void CheckInternetConnection() { StartCoroutine(CheckConnectionCoroutine()); } private IEnumerator CheckConnectionCoroutine() { using (UnityWebRequest request = UnityWebRequest.Head("http://google.com")) { yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { Debug.Log("Internet connection available"); // 网络恢复时关闭面板(仅当面板处于激活状态时) if (isPanelActive) { NoInternetConnectionPanel.SetActive(false); isPanelActive = false; } } else { Debug.Log("No internet connection"); // 无网络时激活面板(仅当面板未激活时) if (!isPanelActive) { NoInternetConnectionPanel.SetActive(true); isPanelActive = true; } } } } }
修复要点
- 用
UnityWebRequest替代.NET的WebRequest,协程内的所有操作均在主线程执行,确保UI调用有效。 - 增加面板状态标记
isPanelActive,避免重复调用SetActive造成无效操作。 - 延长检测间隔至5秒,降低网络请求频率,减少资源消耗。
- 补充网络恢复时关闭面板的逻辑,完善功能闭环。
内容的提问来源于stack exchange,提问作者Raj
相关产品推荐
相关产品推荐

