Загрузить Spritesheet/Atlas через потоковые активы
Я пытаюсь разрешить степень моддинга в моей игре Unity, используя потоковые ресурсы. Я могу импортировать один спрайт без проблем, но я не уверен, как установить импортируемый спрайт потоковых ресурсов в режим спрайта: множественный и срез, который спрайт разбивается на его части.
Вот тестовый класс, который я сейчас использую для импорта:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using PixelsoftGames.Tools2D;
using System.IO;
public class Sandbox : MonoBehaviour
{
SpriteRenderer sRenderer = null;
private void Awake()
{
sRenderer = GetComponent<SpriteRenderer>();
}
private void Start()
{
DirectoryInfo directoryInfo = new DirectoryInfo(Application.streamingAssetsPath);
FileInfo[] allFiles = directoryInfo.GetFiles("*.*");
foreach(FileInfo file in allFiles)
if(file.Name.Contains("Laser"))
StartCoroutine("LoadSprite", file);
}
IEnumerator LoadSprite(FileInfo file)
{
if (file.Name.Contains("meta"))
yield break;
else
{
string fileWithoutExtension = Path.GetFileNameWithoutExtension(file.ToString());
string finalPath;
WWW localFile;
Texture2D texture;
finalPath = "file://" + file.ToString();
localFile = new WWW(finalPath);
Debug.Log(finalPath);
yield return localFile;
texture = localFile.texture;
texture.filterMode = FilterMode.Point;
Sprite sprite = Sprite.Create(texture as Texture2D, new Rect(0, 0, texture.width, texture.height), new Vector2(0.5f, 0.5f), 32f);
sRenderer.sprite = sprite;
}
}
}
2 ответа
Вы не можете просто поместить лист Sprite в папку StreamingAssets и ожидать доступа к нему непосредственно в сборке. Поскольку лист Sprite имеет формат Unity, для доступа к нему необходимо использовать один из API ресурсов / ресурсов Unity. Есть два способа сделать это:
1. С Resources
API. Это означает, что вы должны использовать папку ресурсов вместо папки StreamingAssets. Поместите атлас Sprite в папку "Ресурсы", затем прочитайте следующее:
Sprite[] sprite = Resources.LoadAll<Sprite>("spriteFile") as Sprite[];
2. Если вы хотите использовать папку StreamingAssets, вы должны построить лист Sprite как Assetbundle, а затем использовать AssetBundle
API читает его во время выполнения. AssetBundle.LoadAssetWithSubAssets
а также AssetBundle.LoadAssetWithSubAssetsAsync
(Рекомендуемые) функции используются для загрузки атласа Sprite.
Этот пост показывает, как построить AssetBundle. Игнорируйте загружаемую часть, потому что загрузка атласа спрайта отличается от загрузки обычной текстуры. Как только вы соберете его, смотрите ниже, как его загрузить. Атлас спрайтов хранится в loadedSprites
переменная:
public Image image;
string nameOfAssetBundle = "animals";
string nameOfObjectToLoad = "dog";
void Start()
{
StartCoroutine(LoadAsset(nameOfAssetBundle, nameOfObjectToLoad));
}
IEnumerator LoadAsset(string assetBundleName, string objectNameToLoad)
{
string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "AssetBundles");
filePath = System.IO.Path.Combine(filePath, assetBundleName);
//Load "animals" AssetBundle
var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(filePath);
yield return assetBundleCreateRequest;
AssetBundle asseBundle = assetBundleCreateRequest.assetBundle;
//Load the "dog" Asset (Use Sprite since it's a Sprite. Use GameObject if prefab)
AssetBundleRequest asset = asseBundle.LoadAssetWithSubAssetsAsync<Sprite>(objectNameToLoad);
yield return asset;
//Retrive all the Object atlas and store them in loadedSprites Sprite
UnityEngine.Object[] loadedAsset = asset.allAssets as UnityEngine.Object[];
Sprite[] loadedSprites = new Sprite[loadedAsset.Length];
for (int i = 0; i < loadedSprites.Length; i++)
loadedSprites[i] = (Sprite)loadedAsset[i];
Debug.Log("Atlas Count: " + loadedSprites.Length);
for (int i = 0; i < loadedSprites.Length; i++)
{
Debug.LogWarning(loadedSprites[i].name);
//Do something with the loaded loadedAsset object (Load to Image component for example)
image.sprite = loadedSprites[i];
}
}
Начиная с предварительной версии 1.17.x, вы можете использовать следующий синтаксис:
myAddressableSpriteSheet.LoadAssetAsync<Sprite[]>();
Когда myAddressableSpriteSheet является AssetReferenceTexture2D. Этот функционал пока нигде не документирован, но упоминался на форуме Unity .