Обычно вместо системных путей лучше использовать Path.Combine
, например
var path = Path.Combine(Application.persistentDataPath, FileName);
!Возможно, ваше целевое устройство просто не понимает /
как разделитель пути.
И либо напишите также, если файл уже существует (возможно, более новая версия? И вы уже загрузили его в любом случае) илиВам даже не следует начинать загрузку, если она уже существует для экономии пропускной способности.
Я также думаю, что WriteAllText
не совсем правильное решение для двоичных данных изображения, поскольку www.downloadHandler.text
уже
интерпретируется как строка UTF8
, поэтому, поскольку в изображении, скорее всего, есть несколько байтов, которые не могут быть представлены в строке UTF8, вы получите здесь поврежденные данные!
Вам лучше использовать
www.downloadHandler.data
, который вместо этого возвращает необработанный byte[]
и, например, File.WriteAllBytes
(только для UWP) или правильный FileStream
для записи этого byte[]
в файл.Что-то вроде
var data = www.downloadHandler.data;
File.WriteAllBytes(path, data);
или
var data = www.downloadHandler.data;
using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
fs.Write(data, 0, data.Length);
}
Чем белое изображение на сцене обычно означает, что спрайт равен null
.
Если его нетопечатка, чем ваш LoadSprite
всегда возвращает null
.Вы забыли вернуть созданные sprite
private Sprite LoadSprite(string path)
{
if (string.IsNullOrEmpty(path)) return null;
if (System.IO.File.Exists(path))
{
byte[] bytes = File.ReadAllBytes(path);
Texture2D texture = new Texture2D(900, 900, TextureFormat.RGB24, false);
texture.filterMode = FilterMode.Trilinear;
texture.LoadImage(bytes);
Sprite sprite = Sprite.Create(texture, new Rect(0, 0, 8, 8), new Vector2(0.5f, 0.0f), 1.0f);
// You should return the sprite here!
return sprite;
}
return null;
}
Однако учтите, что лучший способ загрузки также локальных изображений на самом деле UnityWebRequestTexture
.В качестве URL-адреса также используется локальный путь к файлу и
. Использование этого класса значительно сокращает перераспределение памяти по сравнению с загрузкой необработанных байтов и созданием текстуры вручную в сценарии.Кроме того, преобразование текстур будет выполняться в рабочем потоке.
Но также
Поддерживаются только форматы JPG и PNG.
но это не должно быть проблемой, я думаю, поскольку LoadImage
, который вы использовали до сих пор, лежит в основе того же ограничения.
Однако это будет асинхронно, поэтому вам придется подождать текстуру, чтобысоздать спрайт.Поэтому вместо перенастройки Sprite
я бы предпочел передать ссылку на соответствующий компонент Image
и напрямую заменить его sprite
.Что-то вроде
private IEnumerator LoadLocalTexture(string path, Image receivingImage)
{
UnityWebRequest www = UnityWebRequestTexture.GetTexture(path);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
var texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
var sprite = Sprite.Create(texture, new Rect(0, 0, 8, 8), new Vector2(0.5f, 0.0f), 1.0f);
receivingImage.sprite = sprite;
}
}
Если вы не обязаны использовать на самом деле Sprites
, я бы всегда рекомендовал вместо этого использовать RawImage
компоненты, которые вместо этого могут напрямую использовать Texture2D
!И затем сделать что-то вроде
private IEnumerator LoadLocalTexture(string path, RawImage receivingImage)
{
UnityWebRequest www = UnityWebRequestTexture.GetTexture(path);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError)
{
Debug.Log(www.error);
}
else
{
var texture = ((DownloadHandlerTexture)www.downloadHandler).texture;
receivingImage.texture = texture;
}
}
, но также
Примечание: имейте в виду, что использование RawImage создает дополнительный вызов отрисовки с каждым присутствующим RawImage, поэтому лучше использовать еготолько для фона или временно видимой графики.