11.UniTask请求网络图片

  1. 11.请求网络图片
    1. 11.1 知识点
      1. 协程与 UniTask 加载网络图片对比
        1. 测试脚本实现
        2. 核心机制对比
      2. 总结
    2. 11.2 知识点代码
      1. Lesson11_请求网络图片.cs

11.请求网络图片


11.1 知识点

协程与 UniTask 加载网络图片对比

测试脚本实现

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;

/// <summary>
/// 网络图片加载示例:演示协程与UniTask加载图片的对比
/// </summary>
public class Lesson11_请求网络图片 : MonoBehaviour
{
    [Header("协程加载配置")]
    [Tooltip("加载按钮(协程方式)")]
    public Button btn1;         // 协程加载按钮

    [Tooltip("显示图片的Image组件(协程方式)")]
    public Image img1;          // 协程加载的图片显示组件

    [Header("UniTask加载配置")]
    [Tooltip("加载按钮(UniTask方式)")]
    public Button btn2;         // UniTask加载按钮

    [Tooltip("显示图片的Image组件(UniTask方式)")]
    public Image img2;          // UniTask加载的图片显示组件

    [Header("图片资源地址")]
    [Tooltip("百度logo图片URL")]
    public string url = "https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png";

    void Start()
    {
        // 协程加载按钮绑定协程方法
        btn1.onClick.AddListener(() => StartCoroutine(NormalRequest()));
        
        // UniTask加载按钮绑定异步方法,使用Forget()忽略警告
        btn2.onClick.AddListener(() => UniTaskImg().Forget());
    }

    /// <summary>
    /// 传统协程加载图片方法
    /// </summary>
    private IEnumerator NormalRequest()
    {
        // 使用using语句自动释放WebRequest资源
        using var webRequest = UnityWebRequestTexture.GetTexture(url);
        
        // 发送网络请求并等待完成
        yield return webRequest.SendWebRequest();

        // 检查请求结果
        if (webRequest.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError)
        {
            Debug.LogError($"请求失败: {webRequest.error}"); // 打印错误信息
        }
        else
        {
            if (!webRequest.isDone) yield break; // 请求未完成则终止

            // 从下载处理器中获取纹理
            var texture = ((DownloadHandlerTexture)webRequest.downloadHandler).texture;
            
            // 创建Sprite并设置到Image组件
            Sprite sprite = Sprite.Create(texture,
                new Rect(Vector2.zero, new Vector2(texture.width, texture.height)),
                new Vector2(0.5f, 0.25f)); // 锚点设置为中心偏上
            img1.sprite = sprite;
        }
    }

    /// <summary>
    /// UniTask异步加载图片方法
    /// </summary>
    private async UniTaskVoid UniTaskImg()
    {
        // 创建WebRequest实例
        var webRequest = UnityWebRequestTexture.GetTexture(url);
        
        // 发送请求并等待完成(无需手动管理协程)
        await webRequest.SendWebRequest();

        // 从下载处理器中获取纹理
        var texture = ((DownloadHandlerTexture)webRequest.downloadHandler).texture;

        // 创建Sprite并设置到Image组件
        Sprite sprite = Sprite.Create(texture,
            new Rect(Vector2.zero, new Vector2(texture.width, texture.height)),
            new Vector2(0.5f, 0.25f)); // 锚点设置为中心偏上
        img2.sprite = sprite;
    }
}

核心机制对比

特性 协程 (IEnumerator) UniTask (async/await)
代码结构 需要手动管理协程生命周期 异步代码更简洁直观
异常处理 需在协程内部捕获异常 支持全局异常处理器
性能开销 每次 yield return 产生GC分配 无额外分配(基于IL2CPP优化)
取消支持 需自定义取消逻辑 原生支持CancellationToken

总结

  1. 优先使用 UniTask:减少GC分配和代码复杂度
  2. 避免 async void:使用 UniTaskVoid 并配合 Forget()
  3. 取消支持:为网络请求添加 CancellationToken

11.2 知识点代码

Lesson11_请求网络图片.cs

using System.Collections;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
using Cysharp.Threading.Tasks;

/// <summary>
/// 网络图片加载示例:演示协程与UniTask加载图片的对比
/// </summary>
public class Lesson11_请求网络图片 : MonoBehaviour
{
    [Header("协程加载配置")] [Tooltip("加载按钮(协程方式)")]
    public Button btn1; // 协程加载按钮

    [Tooltip("显示图片的Image组件(协程方式)")] public Image img1; // 协程加载的图片显示组件

    [Header("UniTask加载配置")] [Tooltip("加载按钮(UniTask方式)")]
    public Button btn2; // UniTask加载按钮

    [Tooltip("显示图片的Image组件(UniTask方式)")] public Image img2; // UniTask加载的图片显示组件

    [Header("图片资源地址")] [Tooltip("百度logo图片URL")]
    public string url = "https://www.baidu.com/img/PCfb_5bf082d29588c07f842ccde3f97243ea.png";

    void Start()
    {
        // 协程加载按钮绑定协程方法
        btn1.onClick.AddListener(() => StartCoroutine(NormalRequest()));

        // UniTask加载按钮绑定异步方法,使用Forget()忽略警告
        btn2.onClick.AddListener(() => UniTaskImg().Forget());
    }

    /// <summary>
    /// 传统协程加载图片方法
    /// </summary>
    private IEnumerator NormalRequest()
    {
        // 使用using语句自动释放WebRequest资源
        using var webRequest = UnityWebRequestTexture.GetTexture(url);

        // 发送网络请求并等待完成
        yield return webRequest.SendWebRequest();

        // 检查请求结果
        if (webRequest.result is UnityWebRequest.Result.ConnectionError or UnityWebRequest.Result.ProtocolError)
        {
            Debug.LogError($"请求失败: {webRequest.error}"); // 打印错误信息
        }
        else
        {
            if (!webRequest.isDone) yield break; // 请求未完成则终止

            // 从下载处理器中获取纹理
            var texture = ((DownloadHandlerTexture)webRequest.downloadHandler).texture;

            // 创建Sprite并设置到Image组件
            Sprite sprite = Sprite.Create(texture,
                new Rect(Vector2.zero, new Vector2(texture.width, texture.height)),
                new Vector2(0.5f, 0.25f)); // 锚点设置为中心偏上
            img1.sprite = sprite;
        }
    }

    /// <summary>
    /// UniTask异步加载图片方法
    /// </summary>
    private async UniTaskVoid UniTaskImg()
    {
        // 创建WebRequest实例
        var webRequest = UnityWebRequestTexture.GetTexture(url);

        // 发送请求并等待完成(无需手动管理协程)
        await webRequest.SendWebRequest();

        // 从下载处理器中获取纹理
        var texture = ((DownloadHandlerTexture)webRequest.downloadHandler).texture;

        // 创建Sprite并设置到Image组件
        Sprite sprite = Sprite.Create(texture,
            new Rect(Vector2.zero, new Vector2(texture.width, texture.height)),
            new Vector2(0.5f, 0.25f)); // 锚点设置为中心偏上
        img2.sprite = sprite;
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏