| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451 | using System;using System.Collections;using System.Collections.Generic;using System.IO;using System.Linq;using UnityEngine;using UnityEngine.Networking;using UnityEngine.UI;public class TextureLoadHelp : MonoBehaviour{    public static TextureLoadHelp _Instance;    private Dictionary<string, TempTexData> tempTexList;    private Dictionary<long, Material> waitLoadImgActionList;    private Dictionary<long, RawImage> waitLoadImgActionList_RawImg;        public float currentTotalSize = 0;    public float maxSize = 500; //图片缓存-m    private Dictionary<string, AssetBundle> loadDoneABList;    private Dictionary<string, int> loadingABList;    public Texture map_def;        //临时存的封面图    public Texture[] tempTextures;    public string[] tempTextureName;    public Texture GetTempTexture(string name)    {        int index = -1;        for (int i = 0; i < tempTextureName.Length; i++)        {            if (tempTextureName[i].Equals(name))            {                index = i;                break;            }        }        if (index != -1)        {            return tempTextures[index];        }        else        {            return null;        }    }    private void Awake()    {        _Instance = this;        tempTexList = new Dictionary<string, TempTexData>();        waitLoadImgActionList = new Dictionary<long, Material>();        waitLoadImgActionList_RawImg = new Dictionary<long, RawImage>();        loadDoneABList = new Dictionary<string, AssetBundle>();        loadingABList = new Dictionary<string, int>();    }    /// <summary>    /// 加载图片    /// </summary>    /// <param name="path"></param>    /// <param name="rawImg"></param>    /// <returns></returns>    public long LoadTexFromUrl(string path, RawImage rawImg)    {        long loadId = GetDownId();        //Debug.Log("下载图片:"+loadId);        // if (CheckCache(path))        // {        //     rawImg.texture = LoadFromCache(path);        //     return 0;        // }        if (tempTexList.TryGetValue(path, out var value))        {            value.isUsing = true;            rawImg.texture = value.tex;            loadId = 0;        }        else        {            waitLoadImgActionList_RawImg.TryAdd(loadId, rawImg);            StartCoroutine(DownLoadTex_Raw(path, loadId));        }        return loadId;    }    public long LoadTexFromUrl_AB(string ab_Name, string FileName, Material mat)    {        if (tempTexList.TryGetValue(FileName, out var value))        {            value.isUsing = true;            mat.mainTexture = value.tex;            return 0;        }        mat.mainTexture = map_def;        long loadId = GetDownId();        waitLoadImgActionList.Add(loadId, mat);        StartCoroutine(DownLoadTex_AB(ab_Name, FileName, loadId));        return loadId;    }    /// <summary>    /// 取消加载    /// </summary>    /// <param name="loadId"></param>    public void CancelLoad(long loadId)    {        if (waitLoadImgActionList.ContainsKey(loadId))        {            waitLoadImgActionList.Remove(loadId);        }    }    /// <summary>    /// 标记缓存图片为未使用    /// </summary>    /// <param name="path"></param>    public void UnUsingTex(string path)    {        if (tempTexList.TryGetValue(path, out TempTexData disposeData))        {            disposeData.isUsing = false;        }        else        {            Debug.Log($"不存在缓存:{path}");        }    }    IEnumerator DownLoadTex_AB(string ab_Name, string fileName, long loadId)    {        if (loadingABList.ContainsKey(ab_Name))        {            //Debug.Log($"{ab_Name} downloading...wait");            yield return new WaitUntil(() => loadingABList[ab_Name] > 0);            // if (loadingABList.ContainsKey(ab_Name))            // {            //     loadingABList.Remove(ab_Name);            // }        }        AssetBundle tempAb;        Texture2D tex;        if (loadDoneABList.TryGetValue(ab_Name, out var value))        {            tempAb = value;            tex = tempAb.LoadAsset<Texture2D>(fileName);            if (waitLoadImgActionList.TryGetValue(loadId, out Material targetMat))            {                if (targetMat != null && tex != null)                {                    targetMat.mainTexture = tex;                }                else                {                    if (targetMat == null)                    {                        Debug.Log($"{fileName} 材质球不存在");                    }                    if (tex == null)                    {                        Debug.Log($"{fileName} 图片不存在");                    }                }                waitLoadImgActionList.Remove(loadId);            }        }        else        {            //添加到正在下载            loadingABList.TryAdd(ab_Name, 0);#if UNITY_EDITOR            WWW www = new WWW($"{Application.streamingAssetsPath}/{ab_Name}");#else            WWW www = WWW.LoadFromCacheOrDownload($"{Application.streamingAssetsPath}/{ab_Name}",0);#endif            yield return www;            if (www.isDone)            {                tempAb = www.assetBundle;                loadDoneABList.Add(ab_Name, tempAb);                loadingABList[ab_Name] = 1;                tex = tempAb.LoadAsset<Texture2D>(fileName);                tempTexList.TryAdd(fileName, new TempTexData()                {                    loadTime = GetTimeStamp(),                    name = fileName,                    tex = tex,                    size = 0,                    isUsing = true                });                if (waitLoadImgActionList.TryGetValue(loadId, out Material targetMat))                {                    if (targetMat != null && tex != null)                    {                        targetMat.mainTexture = tex;                    }                    else                    {                        if (targetMat == null)                        {                            Debug.Log($"{fileName} 材质球不存在");                        }                        if (tex == null)                        {                            Debug.Log($"{fileName} 图片不存在");                        }                    }                    waitLoadImgActionList.Remove(loadId);                }            }            else            {                loadingABList[ab_Name] = 2;                Debug.LogError($"{ab_Name}下载失败:{www.error}");            }            www.Dispose();        }    }    IEnumerator DownLoadTex(string path, long loadId)    {        UnityWebRequest www = UnityWebRequestTexture.GetTexture(path);        yield return www.SendWebRequest();        if (www.downloadHandler.isDone)        {            if (waitLoadImgActionList.ContainsKey(loadId))            {                var texture = ((DownloadHandlerTexture)www.downloadHandler).texture;                float tempSize = GetSize_m(www.downloadedBytes);                tempTexList.TryAdd(path, new TempTexData()                {                    loadTime = GetTimeStamp(),                    name = path,                    tex = texture,                    size = tempSize,                    isUsing = true                });                currentTotalSize += tempSize;                CheckSize();                if (waitLoadImgActionList.TryGetValue(loadId, out Material targetMat))                {                    if (targetMat != null)                    {                        targetMat.mainTexture = texture;                    }                    waitLoadImgActionList.Remove(loadId);                }                SaveInCache(path, www.downloadHandler.data);            }            else            {                www.disposeDownloadHandlerOnDispose = true;                Debug.Log(path + " 下载已取消");            }        }        else        {            Debug.LogError($"{path}下载失败:{www.downloadHandler.error}");        }        www.Dispose();    }    IEnumerator DownLoadTex_Raw(string path, long loadId)    {        WWW www = new WWW(path);        yield return www;        if (www.isDone)        {            if (waitLoadImgActionList_RawImg.ContainsKey(loadId))            {                var texture = www.texture;                float tempSize = GetSize_m((ulong)www.bytesDownloaded);                tempTexList.TryAdd(path, new TempTexData()                {                    loadTime = GetTimeStamp(),                    name = path,                    tex = texture,                    size = tempSize,                    isUsing = true                });                currentTotalSize += tempSize;                CheckSize();                if (waitLoadImgActionList_RawImg.TryGetValue(loadId, out RawImage rawImage))                {                    if (rawImage != null)                    {                        rawImage.texture = texture;                    }                    waitLoadImgActionList_RawImg.Remove(loadId);                }            }            else            {                Debug.Log(path + " 下载已取消");            }        }        else        {            Debug.LogError($"{path}下载失败:{www.error}");        }        www.Dispose();    }    private void SaveInCache(string url, byte[] data)    {        string fileName = Path.GetFileName(url);        string path = Application.persistentDataPath;        File.WriteAllBytes(path + fileName, data);        Debug.Log($"缓存:{path}{fileName}");    }    private Texture2D LoadFromCache(string url)    {        string fileName = Path.GetFileName(url);        string path = Application.persistentDataPath;        byte[] texBytes = File.ReadAllBytes(path + fileName);        currentTotalSize += GetSize_m((ulong)texBytes.Length);        Texture2D tempTex = new Texture2D(2, 2);        tempTex.LoadImage(texBytes);        tempTex.Apply();        return tempTex;    }    // private bool CheckCache(string url)    // {    //     string fileName = Path.GetFileName(url);    //     string path = Application.persistentDataPath;    //     //Debug.Log($"CaChe:{path}");    //     return File.Exists(path + fileName);    // }    public void CheckSize()    {        if (currentTotalSize >= maxSize)        {            List<TempTexData> values = tempTexList.Values.ToList();            values.Sort();            for (int i = 0; i < values.Count; i++)            {                if (!values[i].isUsing)                {                    if (tempTexList.TryGetValue(values[i].name, out TempTexData disposeData))                    {                        disposeData.tex = null;                        currentTotalSize -= disposeData.size;                        tempTexList.Remove(disposeData.name);                    }                }                if (currentTotalSize < maxSize)                {                    break;                }            }            if (currentTotalSize >= maxSize)            {                Debug.Log($"临时图片已超过限制大小且无可释放项!!!:{currentTotalSize}/{maxSize}");            }        }    }    /// <summary>    /// 清空全部缓存    /// </summary>    public void ClearAllTempTex()    {        List<TempTexData> values = tempTexList.Values.ToList();        for (int i = 0; i < values.Count; i++)        {            if (tempTexList.TryGetValue(values[i].name, out TempTexData disposeData))            {                disposeData.tex = null;                currentTotalSize -= disposeData.size;                tempTexList.Remove(disposeData.name);            }        }        waitLoadImgActionList.Clear();        tempTexList.Clear();        Resources.UnloadUnusedAssets();        GC.Collect();    }    private long GetDownId()    {        long id = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000);        while (waitLoadImgActionList.ContainsKey(id))        {            id++;        }        return id;    }    private long GetTimeStamp()    {        return (DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000;    }    private float GetSize_m(ulong size_b)    {        return (size_b * 1.0f / (1024.0f * 1024.0f));    }}public class TempTexData : IComparable<TempTexData>{    public string name;    public Texture tex;    public long loadTime;    public float size;    public bool isUsing = true;    public int CompareTo(TempTexData other)    {        if (other.loadTime < loadTime)        {            return 1;        }        if (other.loadTime == loadTime)        {            return 0;        }        return -1;    }}
 |