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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 12:31:04