Unity 工具类 之 简单网络下载任务队列服务实现(WWW/UnityWebRequest/下载AssetBundle/Audioclip/Texture2D/Text等)

 

Unity 工具类 之 简单网络下载任务队列服务实现(WWW/UnityWebRequest/下载AssetBundle/Audioclip/Texture2D/Text等)

 

目录

Unity 工具类 之 简单网络下载任务队列服务实现(WWW/UnityWebRequest/下载AssetBundle/Audioclip/Texture2D/Text等)

一、简单介绍

二、实现原理

三、效果预览

四、实现步骤

五、关键代码


 

一、简单介绍

Unity 工具类,自己整理的一些游戏开发可能用到的模块,单独独立使用,方便游戏开发。

简单网络下载任务队列服务,单独做了一个单例类,实现向服务中添加任务,就会自动下载对应的下载任务,可以根据自己的需要添加自己下载后的资源管理,以及扩展其他下载类型的任务和功能,供外界调用。

 

二、实现原理

1、IWWWBase 和 WWWBase ,作为具体的下载类型基类,定义共有方法和属性;

2、WWWAudio 、WWWImage 实现具体类型下载方法和开始下载、下载错误、下载完成的事件(根据需要可以自行拓展);

3、WWWService 负责添加下载任务,并自动下载对应下载任务;

4、简单网络下载任务队列服务 大概的框架如下:

 

 

三、效果预览

 

四、实现步骤

1、打开Unity,新建一个空工程

 

2、在场景中添加 RawImage和Text 用显示下载的图片的和Text文本

 

3、新建脚本,实现各个类型下载,以及 下载服务类,添加任务下载,和一个测试功能的脚本

 

4、把测试脚本对应添加到场景中,并对应的赋值

 

5、运行脚本,会有图片显示、文本显示,以及一个音频播放

6、断网的时候,结果如下

 

五、关键代码

1、TestWWWService

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class TestWWWService : MonoBehaviour
{
    public RawImage rawImage;
    public Text text;
    AudioSource audioSource;

    // Start is called before the first frame update
    void Start()
    {
        audioSource =this.gameObject.AddComponent<AudioSource>();
        Test();
    }

    void Test() {
        string imageUrl = @"https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1752460159,226752426&fm=26&gp=0.jpg";
        WWWImage wImage =  new WWWImage(imageUrl,
            (texture)=> {
                rawImage.texture = (Texture2D)texture;
                if (WWWService.Instance.wImageDic.ContainsKey(imageUrl) == false)
                {
                    WWWService.Instance.wImageDic.Add(imageUrl, (Texture2D)texture);
                }
            });

        string audioUrl = @"http://downsc.chinaz.net/Files/DownLoad/sound1/201702/8369.wav";
        WWWAudio wAudio =  new WWWAudio(audioUrl, 
            (clip) =>{

            audioSource.clip = (AudioClip)clip;
            audioSource.Play();

                if (WWWService.Instance.wAudipDic.ContainsKey(audioUrl) == false)
                {
                    WWWService.Instance.wAudipDic.Add(audioUrl, (AudioClip)clip);
                }
            });

        string txtUrl = @"http://baidu.com";
        WWWText wText =  new WWWText(txtUrl, 
            (txt)=>{
                text.text = (string)txt;

                if (WWWService.Instance.wTextDic.ContainsKey(txtUrl) == false)
                {
                    WWWService.Instance.wTextDic.Add(txtUrl, (string)txt);
                }
            });

        WWWService.Instance.AddWWWTask(wImage);
        WWWService.Instance.AddWWWTask(wAudio);
        WWWService.Instance.AddWWWTask(wText);
    }
}

 

2、WWWService

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class WWWService : MonoSingleton<WWWService>
{
    // 下载队列
    private Queue<WWWBase> allWWWTaskQue = new Queue<WWWBase>();

    #region 数据管理

    internal Dictionary<string, string> wTextDic = new Dictionary<string, string>();
    internal Dictionary<string, Texture2D> wImageDic = new Dictionary<string, Texture2D>();
    internal Dictionary<string, AudioClip> wAudipDic = new Dictionary<string, AudioClip>();

    #endregion

    #region 下载任务

    public void AddWWWTask(WWWBase task) {

        Debug.Log(GetType()+ "/AddWWWTask() Add One WWW Task/");

        allWWWTaskQue.Enqueue(task);

        // 有开始下载
        if (allWWWTaskQue.Count == 1)
        {
            // 协程开始任务下载
            StartCoroutine(DownloadWWWTask());
        }
    }

    IEnumerator DownloadWWWTask() {

        // 循环到下载完为止
        while (allWWWTaskQue.Count > 0)
        {
            WWWBase task = allWWWTaskQue.Dequeue();

            // 等待这个任务下载完
            yield return task.Download();
        }
    }

    #endregion
}

 

3、IWWWBase

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public interface IWWWBase 
{
    //开始下载
    void BeginDownload();

    // 下载出错
    void DownloadError(UnityWebRequest uwr);

    // 下载结束
    void DownloadFinish(UnityWebRequest uwr);

    // 协程下载
    IEnumerator Download();
}

 

4、WWWBase

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class WWWBase : IWWWBase
{
    private string url;   
    public string Url { get => url; set => url = value; }

    protected Action<object> action;

    public WWWBase(string url, Action<object> action = null)
    {
        Url = url;
        this.action = action;
    }


    public virtual void BeginDownload()
    {
    }

    public virtual void DownloadError(UnityWebRequest uwr)
    {
    }

    public virtual void DownloadFinish(UnityWebRequest uwr)
    {
        
    }

    public virtual IEnumerator Download()
    {
        BeginDownload();

        using (UnityWebRequest uwr = UnityWebRequest.Get(Url))
        {
            yield return uwr.SendWebRequest();
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                DownloadFinish(uwr);
            }
            else
            {
                DownloadError(uwr);
            }
        }
    }
}

 

5、WWWAudio

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class WWWAudio : WWWBase
{
    // 最好构建资源管理统一放置
    public AudioClip clip;

    public WWWAudio(string url, Action<object> action = null) : base(url, action)
    {

    }
    


    public override void BeginDownload()
    {
        

        Debug.Log(GetType()+ "/BeginDownload()/ Audio");
    }

    public override void DownloadError(UnityWebRequest uwr)
    {
        

        Debug.Log(GetType() + "/BeginDownload()/ Audio uwr.error : " + uwr.error);
    }

    public override void DownloadFinish(UnityWebRequest uwr)
    {
        clip = DownloadHandlerAudioClip.GetContent(uwr);
        action?.Invoke(clip);
    }

    public override IEnumerator Download()
    {
        BeginDownload();

        using (var uwr = UnityWebRequestMultimedia.GetAudioClip(Url, AudioType.WAV))
        {
            yield return uwr.SendWebRequest();
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                DownloadFinish(uwr);
            }
            else
            {
                DownloadError(uwr);
            }
        }
    }
}

 

6、WWWImage

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class WWWImage : WWWBase
{
    // 最好构建资源管理统一放置
    public Texture2D texture2D;
   


    public WWWImage(string url , Action<object> action = null):base(url,action)
    {
        
    }


    public override void BeginDownload()
    {


        Debug.Log(GetType() + "/BeginDownload()/ Image");
    }

    public override void DownloadError(UnityWebRequest uwr)
    {


        Debug.Log(GetType() + "/BeginDownload()/ Image uwr.error : " + uwr.error);
    }

    public override void DownloadFinish(UnityWebRequest uwr)
    {
        texture2D = ((DownloadHandlerTexture)uwr.downloadHandler).texture;
        action?.Invoke(texture2D);
    }

    public override IEnumerator Download()
    {
        BeginDownload();

        using (UnityWebRequest uwr = new UnityWebRequest(Url))
        {
            DownloadHandlerTexture downloadTexture = new DownloadHandlerTexture(true);
            uwr.downloadHandler = downloadTexture;
            yield return uwr.SendWebRequest();
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                DownloadFinish(uwr);
            }
            else
            {
                DownloadError(uwr);
            }            
        }
    }
}

 

7、WWWText

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

public class WWWText : WWWBase
{
    // 最好构建资源管理统一放置
    public string txtStr;

    public WWWText(string url, Action<object> action = null) : base(url, action)
    {

    }

    public override void BeginDownload()
    {


        Debug.Log(GetType() + "/BeginDownload()/ Text");
    }

    public override void DownloadError(UnityWebRequest uwr)
    {


        Debug.Log(GetType() + "/BeginDownload()/ Text uwr.error : " + uwr.error);
    }

    public override void DownloadFinish(UnityWebRequest uwr)
    {        
        txtStr = uwr.downloadHandler.text;
        action?.Invoke(txtStr);
    }

    public override IEnumerator Download()
    {
        BeginDownload();

        using (UnityWebRequest uwr = UnityWebRequest.Get(Url)) {
        
            yield return uwr.SendWebRequest();
            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                DownloadFinish(uwr);
            }
            else
            {
                DownloadError(uwr);
            }
            
            // 保存本地(酌情处理)
            //File.WriteAllText(@"D:\xxxx.txt", str);
        }
    }
}

 

8、WWWAssetBundle

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Networking;

public class WWWAssetBundle : WWWBase
{
    // 最好构建资源管理统一放置
    public AssetBundle assetBundle;

    public WWWAssetBundle(string url, Action<object> action = null) : base(url, action)
    {

    }


    public override void BeginDownload()
    {
        Debug.Log(GetType() + "/BeginDownload()/ AssetBundle");
    }

    public override void DownloadError(UnityWebRequest uwr)
    {


        Debug.Log(GetType() + "/BeginDownload()/ AssetBundle uwr.error : " + uwr.error);
    }

    public override void DownloadFinish(UnityWebRequest uwr)
    {
        assetBundle = ((DownloadHandlerAssetBundle)uwr.downloadHandler).assetBundle;
    }

    public override IEnumerator Download()
    {
        BeginDownload();

        using (UnityWebRequest uwr = new UnityWebRequest(Url))
        {
            DownloadHandlerAssetBundle handler = new DownloadHandlerAssetBundle(uwr.url, uint.MaxValue);
            uwr.downloadHandler = handler;
            yield return uwr.SendWebRequest();

            if (!(uwr.isNetworkError || uwr.isHttpError))
            {
                DownloadFinish(uwr);
            }
            else
            {
                DownloadError(uwr);
            }

        }
    }
}

 

9、MonoSingleton

using UnityEngine;

public abstract class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
    private static T instance = null;

    private static readonly object locker = new object();

    private static bool bAppQuitting;

    public static T Instance
    {
        get
        {
            if (bAppQuitting)
            {
                instance = null;
                return instance;
            }

            lock (locker)
            {
                if (instance == null)
                {
                    instance = FindObjectOfType<T>();
                    if (FindObjectsOfType<T>().Length > 1)
                    {
                        Debug.LogError("不应该存在多个单例!");
                        return instance;
                    }

                    if (instance == null)
                    {
                        var singleton = new GameObject();
                        instance = singleton.AddComponent<T>();
                        singleton.name = "(singleton)" + typeof(T);
                        singleton.hideFlags = HideFlags.None;
                        DontDestroyOnLoad(singleton);
                    }
                    else
                        DontDestroyOnLoad(instance.gameObject);
                }
                instance.hideFlags = HideFlags.None;
                return instance;
            }
        }
    }

    private void Awake()
    {
        bAppQuitting = false;
    }

    private void OnDestroy()
    {
        bAppQuitting = true;
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

仙魁XAN

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值