我有一个场景,我想要显示从服务器下载的多个图像。我正在尝试下载纹理并将它们存储在List中。当for循环完成运行时,我按名称对List进行排序,然后从List中实例化RawImage,但不起作用。我做错了什么?
public GameObject contentRef;
public RawImage imgPrefab;
void Start()
{
StartCoroutine(DownloadtheFiles());
}
public IEnumerator DownloadtheFiles()
{
yield return null;
List<string> photolist = ES2.LoadList<string>("myPhotos.txt");
for (int i = 0; i < photolist.Count; i++)
{
//Don't capture i variable
int index = i;
bool reqDone = false;
new GetUploadedRequest()
.SetUploadId(photolist[index])
.Send((response) =>
{
StartCoroutine(DownloadImages(response.Url, index,
(status) => { reqDone = status; }));
//return null;
});
//Wait in the for loop until the current request is done
while (!reqDone)
yield return null;
}
}
public IEnumerator DownloadImages(string downloadUrl, int index, Action<bool> done)
{
var www = new WWW(downloadUrl);
yield return www;
//Get the downloaded image
Texture2D tex = new Texture2D(4, 4);
www.LoadImageIntoTexture(tex);
List <Texture2D> texList = new List <Texture2D> ();
for (int i = 0; i < tex.Count; i++)
{
texList.Add (tex);
}
texList = texList.OrderBy(mtex => mtex.name).ToList();
for (int i = 0; i < tex.Count; i++)
{
RawImage newImg = Instantiate(imgPrefab, contentRef.transform);
//Change the name
newImg.name = "Image-" + index;
//Apply the downloaded image
newImg.texture = tex;
}
//Done
if (done != null)
done(true);
}
}
答案 0 :(得分:1)
您的RawImage
代码应在DownloadImages
函数之外完成,因为DownloadImages
被调用以从for
循环中的网址下载图片。 RawImage
实例化应该仅在for
循环完成后才能完成。
另外,使用texList.OrderBy(mtex => mtex.name).ToList();
不会起作用,因为你的字符串包含字符串和int,并且格式为&#34; Image - &#34; + 0;&#34; 。您需要使用自定义函数来分割string
和int
,然后使用int
进行排序。
最后,在for
循环运行完毕后,您需要一种方法来确定在实例化RawImages
之前所有图像都已完成下载。您可以使用包含要下载的图像链接的bool
大小的List<string> photolist
数组或列表来执行此操作。将该bool数组传递给DownloadImages
,并在每次下载完成后使用index
参数将其设置为true
。
public GameObject contentRef;
public RawImage imgPrefab;
List<Texture2D> downloadedTextures = new List<Texture2D>();
void Start()
{
DownloadtheFiles();
}
public void DownloadtheFiles()
{
List<string> photolist = ES2.LoadList<string>("myPhotos.txt");
//Used to determine when were done downloading
bool[] doneDownloading = new bool[photolist.Count];
//Download images only.Don't instantiate anything
for (int i = 0; i < photolist.Count; i++)
{
//Don't capture i variable
int index = i;
new GetUploadedRequest()
.SetUploadId(photolist[index])
.Send((response) =>
{
StartCoroutine(DownloadImages(response.Url, index, doneDownloading));
});
}
//Instantiate the download images
StartCoroutine(InstantiateImages(doneDownloading));
}
//Instantiates the downloaded images after they are done downloading
IEnumerator InstantiateImages(bool[] downloadStatus)
{
//Wait until all images are done downloading
for (int i = 0; i < downloadStatus.Length; i++)
{
while (!downloadStatus[i])
yield return null;
}
//Sort the images by string
sort(ref downloadedTextures);
//Now, instantiate the images
for (int i = 0; i < downloadedTextures.Count; i++)
{
//Instantiate the image prefab GameObject and make it a child of the contentRef
RawImage newImg = Instantiate(imgPrefab, contentRef.transform);
//Apply the downloaded image
newImg.texture = downloadedTextures[i];
//Update name so that we can see the names in the Hierarchy
newImg.name = downloadedTextures[i].name;
}
//Clear List for next use
downloadedTextures.Clear();
}
//Sort the downloaded Textures by name
void sort(ref List<Texture2D> targetList)
{
var ordered = targetList.Select(s => new { s, Str = s.name, Split = s.name.Split('-') })
.OrderBy(x => int.Parse(x.Split[1]))
.ThenBy(x => x.Split[0])
.Select(x => x.s)
.ToList();
targetList = ordered;
}
public IEnumerator DownloadImages(string downloadUrl, int index, bool[] downloadStatus)
{
//Download image
var www = new WWW(downloadUrl);
yield return www;
//Get the downloaded image and add it to the List
Texture2D tex = new Texture2D(4, 4);
//Change the name
tex.name = "Image-" + index;
www.LoadImageIntoTexture(tex);
downloadedTextures.Add(tex);
downloadStatus[index] = true;
}