Unity协程下载网络文本资源失败问题求助
问题分析与解决方案
核心问题排查方向
- 单例逻辑导致协程宿主被销毁,请求中断
- UnityWebRequest资源未正确释放,引发请求阻塞
- 缺少超时机制,请求卡住后无限等待
- 网络权限或URL配置异常
具体修复步骤
1. 修正单例逻辑,避免协程中断
原代码中若当前GameManager不是首个实例,会被立即销毁,导致其启动的所有协程直接终止。需将初始化逻辑移至单例保留分支内:
public void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(this.gameObject); // 仅保留的实例执行初始化 Debug.Log(FirstTimeChecking.checkIsFirstTime()); if (FirstTimeChecking.checkIsFirstTime()) { StartCoroutine(NetworkManager.DownloadTextCoroutine("https://xxx/words.txt", result => { words = result; isWordsDownloaded = true; })); StartCoroutine(NetworkManager.DownloadIdiomCoroutine("https://xxx/idioms.txt", result => { idioms = result; isIdiomsDownloaded = true; })); StartCoroutine(WaitForDownloads()); } else { playerData = playerDataLoader.playerData; } } else { Destroy(this.gameObject); } }
2. 完善UnityWebRequest资源释放
使用完毕后必须调用Dispose()释放资源,避免内存泄漏或请求阻塞:
public static IEnumerator DownloadTextCoroutine(string url, Action<string> callback) { UnityWebRequest web = UnityWebRequest.Get(url); yield return web.SendWebRequest(); if (web.result != UnityWebRequest.Result.Success) { Debug.LogError(web.error); callback?.Invoke(null); // 通知回调下载失败 } else { callback?.Invoke(web.downloadHandler.text); } // 强制释放资源 web.Dispose(); }
3. 增加超时机制,避免无限等待
原等待逻辑无超时限制,添加超时判断防止请求卡住:
private IEnumerator WaitForDownloads() { const float timeout = 10f; // 设置10秒超时阈值 float elapsedTime = 0f; while ((!isWordsDownloaded || !isIdiomsDownloaded) && elapsedTime < timeout) { elapsedTime += Time.deltaTime; yield return null; } if (elapsedTime >= timeout) { Debug.LogError("下载超时,请检查网络连接或URL有效性"); return; } initPlayerData(words, idioms); }
4. 检查网络权限与URL配置
- Android平台:在
PlayerSettings > Android > Publishing Settings中勾选Internet权限 - HTTP协议URL:在
PlayerSettings > Other Settings > Configuration中,将Allow downloads over HTTP设置为Allowed或Allowed for development - URL验证:直接在浏览器中访问目标URL,确认能正常返回文本内容
5. 可选:改用独立托管的协程启动方式
将NetworkManager改为持久化单例,避免依赖GameManager的生命周期:
public class NetworkManager : MonoBehaviour { private static NetworkManager instance; private void Awake() { if (instance == null) { instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } public IEnumerator DownloadTextCoroutine(string url, Action<string> callback) { UnityWebRequest web = UnityWebRequest.Get(url); yield return web.SendWebRequest(); if (web.result != UnityWebRequest.Result.Success) { Debug.LogError(web.error); callback?.Invoke(null); } else { callback?.Invoke(web.downloadHandler.text); } web.Dispose(); } // 静态方法封装协程启动 public static void StartTextDownload(string url, Action<string> callback) { instance?.StartCoroutine(instance.DownloadTextCoroutine(url, callback)); } }
在GameManager中调用:
NetworkManager.StartTextDownload("https://xxx/words.txt", result => { words = result; isWordsDownloaded = true; });
验证方法
在回调函数中添加日志,确认是否收到数据:
StartCoroutine(NetworkManager.DownloadTextCoroutine("https://xxx/words.txt", result => { Debug.Log("Words下载结果: " + (result ?? "下载失败")); words = result; isWordsDownloaded = true; }));
内容的提问来源于stack exchange,提问作者lemonofgreen
相关产品推荐
相关产品推荐

