как показать изображения в едином изображении заранее, что их ссылки хранятся в массиве - PullRequest
0 голосов
/ 17 января 2019

Я разрабатываю приложение в единстве, которое будет показывать название и изображение предметов из базы данных.Я использую префабы для отображения имени и изображений, но я не знаю, как отображать изображения в префабах из массива URL-адресов (ссылок).

Я сделал префаб

newObj.transform.GetChild(2).GetComponent<Image>().sprite = GetItems.getItems.itemsimage[i];

, чтобы показать изображения в единстве, но я не знаю, как отобразить

public void PopulateItems(int categoryBtnClick)
{
    GameObject newObj;
    for (int i = 0; i < GetItems.getItems.itemsData.Length-1; i++)
    {
        int cat_id = int.Parse(GetItems.getItems.category_id[i]);
         if (cat_id == categoryBtnClick) //cat_id and categoryBtnClick contains id of item
         {
             newObj = (GameObject)Instantiate(itemScrollviewPrefab, transform);
             newObj.transform.GetChild(0).GetComponent<Text>().text =GetItems.getItems.itemsName[i];
             newObj.transform.GetChild(1).GetComponent<Text>().text = GetItems.getItems.itemsId[i];
             if (GetItems.getItems.itemsModel[i] != null)
             {
                 newObj.transform.GetChild(2).GetComponent<Image>().sprite =GetItems.getItems.itemsimage[i] ; //itemsimage[i] contains link of image
             }
             newObj.transform.GetChild(3).GetComponent<Text>().text = GetItems.getItems.itemsPrice[i];
             newObj.transform.GetChild(4).GetComponent<Text>().text = GetItems.getItems.itemsDescription[i];
             newObj.transform.parent = itemContentParent.transform; 
         }
     }
}

Я ожидаю, что каждый раз, когда цикл запускаетсяизображение на этом указателе будет напечатано на единстве

1 Ответ

0 голосов
/ 17 января 2019

RawImage не имеет sprite, но предполагает Texture.

Вы не можете просто передать URL. Вам нужно загрузить текстуру и затем применить результат к rawImage.texture. Пример из документов:

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

public class MyBehaviour : MonoBehaviour 
{
    void Start() 
    {
        StartCoroutine(GetTexture());
    }

    IEnumerator GetTexture() 
    {
        UnityWebRequest www = UnityWebRequestTexture.GetTexture("http://www.my-server.com/image.png");
        yield return www.SendWebRequest();

        if(www.isNetworkError || www.isHttpError) 
        {
            Debug.Log(www.error);
        }
        else 
        {
            Texture myTexture = ((DownloadHandlerTexture)www.downloadHandler).texture;
        }
    }
}

Загрузка происходит асинхронно, поэтому префабы могут появиться до того, как будут загружены все изображения ... это зависит от вас, как вы хотите справиться с этим (например, отображать анимацию загрузки или заполнитель) - я предполагаю, что вы хотите создать экземпляр сразу.

Вы можете просто добавить обратный вызов к методу загрузки, чтобы выполнить любой метод в случае успеха или неудачи:

IEnumerator GetTexture(string url, Action<Texture> successCallback, = null, Action<string> errorCallback = null) 
{
    UnityWebRequest www = UnityWebRequestTexture.GetTexture(url);
    yield return www.SendWebRequest();

    if(www.isNetworkError || www.isHttpError) 
    {
        errorCallback?.Invoke(www.error);
    }
    else 
    {
        successCallback?.Invoke(((DownloadHandlerTexture)www.downloadHandler).texture);
    }
}

и добавьте в ваш код обратные вызовы, например, используя лямбда-выражения , которые должны быть выполнены при успехе или ошибке:

// ...

if (GetItems.getItems.itemsModel[i] != null)
{
    // optional here add a loading or default texture 
    // to be displayed until texture is downloaded e.g.
    newObj.transform.GetChild(2).GetComponent<RawImage>().texture = someDefaultTexture;                         

    // start the download
    StartCoroutine(GetTexture(
        // The url
        GetItems.getItems.itemsimage[i],

        // executed on success
        (s) => 
        {
            OnSuccess(newObj.transform.GetChild(2).GetComponent<RawImage>(), s);
        },

        // optional for visualizing download errors
        (e) =>
        {
            OnError(e);
        }
    ));
}

// ...

и, наконец, реализовать обратные вызовы, например ::1010*

// callback for success download
private void OnSuccess(RawImage rawImage, Texture texture)
{
    rawImage.texture = texture;
}

// callback for download error
private void OnError(RawImage rawImage, string error)
{
    rawImage.Texture = someErrorTexture;
    Debug.Log(error, this);
}

Одно предупреждение о загруженных текстурах (потому что я тоже недавно допустил эту ошибку):

Обычно неиспользуемые / несвязанные текстуры удаляются / удаляются сборщиком мусора, поэтому память вашего устройства не заполняется ... , но очевидно текстуры, созданные с помощью UnityWebRequest, не уничтожаются, даже если они не работают. У меня больше нет ссылок.

Это может привести к утечкам памяти, которые заполняют память вашего устройства загруженными текстурами!

Обязательно активно уничтожайте любую загруженную текстуру, когда она вам больше не нужна, например, добавив скрипт типа

public class CleanUpTexture : MonoBehaviour
{
    private RawImage rawImage;

    private void Awake()
    {
        rawImage = GetComponent<RawImage>();
    }

    private void OnDestroy()
    {
        if(!rawImage || rawImage.texture == null) return;

        Destroy(rawImage.texture);
    }
}

рядом с компонентом RawImage, если эта текстура должна быть уничтожена вместе с объектом.

Это предполагает, конечно, что вы никогда не назначите такую ​​же текстуру ни для чего другого. И это также предполагает, что вы никогда не назначите другую текстуру этому объекту (потому что вы 1. потеряете ссылку на загруженную текстуру и 2. возможно уничтожите текстуру, которую вы не хотели)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...