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. возможно уничтожите текстуру, которую вы не хотели)