Données cartographiques vectorisées, extrudées et spatialisées.
Ou le pipeline GeoJSON, D3.js vers Three.js. Cela fait un moment que nous n'avions pas fait de projet Three.js ! Nous jouons surtout avec Unity, mais c'est toujours agréable de revenir…
Les bonnes pratiques avec Unity ont toujours été un secret bien gardé. Plus précisément concernant le dossier Resources. Heureusement, les choses changent avec le guide des bonnes pratiques de Unity ! Et les choses sont simples concernant les Resources…
Les bonnes pratiques avec Unity ont toujours été un secret bien gardé. Plus précisément concernant le dossier Resources. Heureusement, les choses changent avec le guide des bonnes pratiques de Unity ! Et les choses sont simples concernant le dossier Resources : ne l’utilisez tout simplement pas !
Gérer des Sprites 2D dans Unity est simple si vous avez une scène statique : il suffit de placer chaque sprite nécessaire à l’écran et vous avez presque terminé. Évidemment, vous devriez les regrouper en Spritesheets. Le moyen le plus simple de le faire est via l’outil Sprite Packer de Unity. Mais que faire si vous devez charger des Sprites à l’exécution ? Comment accéder à un Sprite s’il n’est pas lié directement à un GameObject ou un Prefab, et sans utiliser le dossier Resources ?
Créez un ScriptableObject ! C’est la meilleure façon de stocker des informations au sein de Unity. Voici un script d’éditeur pour générer des ScriptableObjects avec une liste de Sprites pour chaque Packing Tag mentionné :
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
[Serializable]
public class SpritesData:ScriptableObject {
[SerializeField]
public Sprite[] sprites;
static public string assetDirPath = "RuntimeSprites/SpritesData/";
static public string assetPath = "Assets/RuntimeSprites/SpritesData/{0}.asset";
#if UNITY_EDITOR
[MenuItem("Data/Create Sprites Data")]
static void CreateSpritesData() {
string dirPath = Application.dataPath + "/" + assetDirPath;
if (!System.IO.Directory.Exists(dirPath))
System.IO.Directory.CreateDirectory(@dirPath);
SpritesData data = ScriptableObject.CreateInstance<SpritesData>();
List<Sprite> spritesList = new List<Sprite>();
string[] anims = AssetDatabase.FindAssets("t:Sprite", new string[] {"Assets/Sprites"});
string currentTag = "";
foreach (string anim in anims) {
string path = AssetDatabase.GUIDToAssetPath(anim);
TextureImporter ti = TextureImporter.GetAtPath(path) as TextureImporter;
if (ti.spritePackingTag != currentTag) {
if (data && currentTag != "") {
data.sprites = spritesList.ToArray();
AssetDatabase.CreateAsset(data, string.Format(assetPath, currentTag));
}
data = ScriptableObject.CreateInstance<SpritesData>();
spritesList = new List<Sprite>();
currentTag = ti.spritePackingTag;
}
Sprite sprite = AssetDatabase.LoadAssetAtPath<Sprite>(path);
spritesList.Add(sprite);
}
data.sprites = spritesList.ToArray();
AssetDatabase.CreateAsset(data, string.Format(assetPath, currentTag));
}
#endif
}
Maintenant que vous avez toutes vos SpritesData, il vous suffit de créer un MonoBehaviour avec une propriété public SpritesData[] spritesDatas;, et vous aurez alors accès à tous vos sprites ! Le bon côté des choses, c’est que tant qu’un sprite n’est pas affiché à l’écran, il n’est pas en mémoire.
À bientôt !