Unity动态载入多个图片到Image(UI)的方法的探讨

需要载入大量图片到Image并显示,基本方法有2种,用WWW或者c#的FileStream。考虑到协程,异步,以及把代码统一写或者分开写,衍生出5、6种方法。

job system只能处理值类型,帮不上忙。ecs也主要集中在处理update里面的内容,似乎也不使用。还考虑过多线程,这里不是很确定。unity多线程过程中,子线程不能使用unity的api,就只能用c#把文件读取过程加速,对多线程不熟,就放弃了。

结论
会出现3种效果,在使用FileStream异步,在统一的地方写代码适应毕竟广。

Unity动态载入多个图片到Image(UI)的方法的探讨_第1张图片

测试方法,加载102张512*512分辨率的图片,显示成一个图片下拉列表,样子如下

Unity动态载入多个图片到Image(UI)的方法的探讨_第2张图片

方法一、统一调用WWW协程

GuiController.CS

//方法一、统一调用WWW协程
GuiController.CS

    /// 
    /// 统一处理WWW协程载入
    /// 
    public void UniteCoroutineWWW()
    {
        //从json获取图片地址信息并转为对象数组
        MediaText[] mts = JsonConvert.DeserializeObject(ifJson.text);
        scrollView.SetActive(true);
 
        //遍历对象数组
        foreach (MediaText mt in mts)
        {
            //实列化游戏对象
            Transform tf = Instantiate(prefab, content);
            tf.GetChild(1).GetComponent().text = mt.Name;
            tf.GetChild(2).GetComponent().text = mt.Description;
            Image image = tf.GetChild(0).GetComponent();
 
            //调用协程
            StartCoroutine(LoadByWWW(mt.Icon, image));
        }
    }
 
    /// 
    /// WWW协程载入图片
    /// 
    /// 图片地址
    /// Image对象
    /// 
    IEnumerator LoadByWWW(string path, Image image)
    {
        path = @"file://"+fileRoot + path;
 
        using (WWW www = new WWW(path))
        {
            yield return www;
            if (www.isDone && www.error == null)
            {
                image.sprite = Sprite.Create(www.texture, new Rect(0, 0, 512f, 512f), new Vector2(0.5f, 0.5f));
            }
            else
            {
                Debug.Log(www.error);
            }
        }
    }


载入情况:先把所有Image初始完成后,统一载入了图片。

Unity动态载入多个图片到Image(UI)的方法的探讨_第3张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第4张图片

cpu占用信息

Unity动态载入多个图片到Image(UI)的方法的探讨_第5张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第6张图片

方法二、统一调用WWW载入,不使用协程
GuiController.CS

   

/// 
    /// 统一调用WWW,不使用协程
    /// 
    public void UniteSynchronizeWWW()
    {
        string path = @"file://"+fileRoot;
        MediaText[] mts = JsonConvert.DeserializeObject(ifJson.text);
        scrollView.SetActive(true);
        foreach (MediaText mt in mts)
        {
            Transform tf = Instantiate(prefab, content);
            tf.GetChild(1).GetComponent().text = mt.Name;
            tf.GetChild(2).GetComponent().text = mt.Description;
            Image image = tf.GetChild(0).GetComponent();
 
            using (WWW www = new WWW(path+mt.Icon))
            {
                while (!www.isDone)
                {
                    if (www.error == null)
                    {
                        image.sprite = Sprite.Create(www.texture, new Rect(0, 0, 512f, 512f), new Vector2(0.5f, 0.5f));
                    }
                    else
                    {
                        Debug.Log(www.error);
                    }
                }
            }
        }
}


载入情况,会等所有内容准备好后一并显示

Unity动态载入多个图片到Image(UI)的方法的探讨_第7张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第8张图片

cpu占用信息

Unity动态载入多个图片到Image(UI)的方法的探讨_第9张图片

方法三、统一FileStream异步
GuiController.CS

   

/// 
    /// 异步载入图片
    /// 
    /// 路径
    /// Image对象
    /// 
    async Task LoadByFSAsync(string path, Image image)
    {
        path = fileRoot + path;
        byte[] result;
 
        using (FileStream SourceStream = File.Open(path, FileMode.Open))
        {
            result = new byte[SourceStream.Length];
            await SourceStream.ReadAsync(result, 0, (int)SourceStream.Length);
        }
 
        Texture2D tx = new Texture2D(512, 512);
        tx.LoadImage(result);
        image.sprite = Sprite.Create(tx, new Rect(0, 0, 512f, 512f), new Vector2(0.5f, 0.5f));
    }
 
    /// 
    /// 统一异步载入
    /// 
    public async void UniteFSAsync()
    {
        MediaText[] mts = JsonConvert.DeserializeObject(ifJson.text);
        scrollView.SetActive(true);
        foreach (MediaText mt in mts)
        {
            Transform tf = Instantiate(prefab, content);
            tf.GetChild(1).GetComponent().text = mt.Name;
            tf.GetChild(2).GetComponent().text = mt.Description;
            Image image = tf.GetChild(0).GetComponent();
 
            await LoadByFSAsync(mt.Icon, image);
        }
}


载入情况:会顺序将对象实例化并载入图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第10张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第11张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第12张图片

 

cpu占用

Unity动态载入多个图片到Image(UI)的方法的探讨_第13张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第14张图片

方法四、由游戏对象自己用WWW协程载入
GuiController.CS   

 /// 
    /// 由游戏对象自己载入图片
    /// 
    public void SelfLoad()
    {
        MediaText[] mts = JsonConvert.DeserializeObject(ifJson.text);
        scrollView.SetActive(true);
        foreach (MediaText mt in mts)
        {
            Transform tf = Instantiate(prefab, content);
            tf.GetChild(1).GetComponent().text = mt.Name;
            tf.GetChild(2).GetComponent().text = mt.Description;
            LoadImage loadImage = tf.GetComponent();
            loadImage.path = fileRoot + mt.Icon;
            //LoadImageDestory lid = tf.GetComponent();
            //lid.path = fileRoot + mt.Icon;
        }
}
LoadImage.CS

    void Start () {
        image = transform.GetChild(0).GetComponent();
        StartCoroutine(LoadByWWW(path, image)); 
        //LoadByFSAsync(path, image); 
    }
 
    /// 
    /// 用WWW协程载入图片
    /// 
    /// 
    /// 
    /// 
    IEnumerator LoadByWWW(string path, Image image)
    {
        path = @"file://" + path;
        using (WWW www = new WWW(path))
        {
            yield return www;
            if (www.isDone && www.error == null)
            {
                image.sprite = Sprite.Create(www.texture, new Rect(0, 0, 512f, 512f), new Vector2(0.5f, 0.5f));
            }
            else
            {
                Debug.Log(www.error);
            }
        }
    }


载入情况:先把所有Image初始完成后,统一载入了图片。

Unity动态载入多个图片到Image(UI)的方法的探讨_第15张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第16张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第17张图片

cpu占用

Unity动态载入多个图片到Image(UI)的方法的探讨_第18张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第19张图片

方法五,由游戏对象自己用FileStream异步载入
GuiController.CS   

 /// 
    /// 由游戏对象自己载入图片
    /// 
    public void SelfLoad()
    {
        MediaText[] mts = JsonConvert.DeserializeObject(ifJson.text);
        scrollView.SetActive(true);
        foreach (MediaText mt in mts)
        {
            Transform tf = Instantiate(prefab, content);
            tf.GetChild(1).GetComponent().text = mt.Name;
            tf.GetChild(2).GetComponent().text = mt.Description;
            LoadImage loadImage = tf.GetComponent();
            loadImage.path = fileRoot + mt.Icon;
            //LoadImageDestory lid = tf.GetComponent();
            //lid.path = fileRoot + mt.Icon;
        }
}
LoadImage.CS

    void Start () {
        image = transform.GetChild(0).GetComponent();
        //StartCoroutine(LoadByWWW(path, image)); 
        LoadByFSAsync(path, image); 
    }
 
    async Task LoadByFSAsync(string path, Image image)
    {
        byte[] result;
 
        using (FileStream SourceStream = File.Open(path, FileMode.Open))
        {
            result = new byte[SourceStream.Length];
            await SourceStream.ReadAsync(result, 0, (int)SourceStream.Length);
        }
 
        Texture2D tx = new Texture2D(512, 512);
        tx.LoadImage(result);
        image.sprite = Sprite.Create(tx, new Rect(0, 0, 512f, 512f), new Vector2(0.5f, 0.5f));
    }


载入情况,会等所有内容准备好后一并显示

Unity动态载入多个图片到Image(UI)的方法的探讨_第20张图片

Unity动态载入多个图片到Image(UI)的方法的探讨_第21张图片

cpu占用信息

Unity动态载入多个图片到Image(UI)的方法的探讨_第22张图片

你可能感兴趣的:(Unity)