CommunityImagegithub.com

qhenshaw/unity-model-icon-renderer

Génère des icônes de sprite à partir de modèles 3D ou prefabs Unity (URP) avec contour, transparence et cadrage automatique adapté à la taille des emplacements d'inventaire.

Qu'est-ce que unity-model-icon-renderer ?

Ce skill pour agents IA (Claude Code, Cursor, Codex, etc.) génère des icônes de sprite pour inventaires, boutiques ou grilles de sac à dos à partir des modèles 3D d'un projet Unity (URP). Il crée une scène de prévisualisation isolée avec une caméra orthographique, trois lumières directionnelles, un rendu suréchantillonné 2× et un contour foncé pour garantir la lisibilité sur tout fond. Le pose des modèles est automatique : les objets allongés (épées, bâtons) sont placés en diagonale dans les emplacements carrés, tandis que les objets compacts (gemmes, potions) sont testés sur plusieurs orientations pour maximiser le nombre de pixels de silhouette. Le skill propose un workflow complet : copie du script d'édition, appel par lots (jobs), import des PNG en sprites, et un script Python de feuille de contact pour vérifier visuellement chaque icône. Il gère les cas particuliers (modèles à plat, enfants pivotés, objets trop petits) via des overrides de rotation et des règles de placement. Idéal pour remplacer des icônes manquantes, régénérer après des changements d'art, ou créer un style "Backpack Battles".

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/qhenshaw/quins-unity-skills/tree/HEAD/skills/unity-model-icon-renderer

Installed? Explore more Image skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Icônes d'objets rendues à partir de modèles 3D

Transformez les propres prefabs du jeu en sprites d'icônes cohérents à partir du code : une scène de prévisualisation isolée, une caméra orthographique avec trois lumières directionnelles, une pose choisie par modèle un rendu suréchantillonné 2×, un sous-échantillonnage prémultiplié, et un contour sombre pour que les icônes soient lisibles sur n'importe quel fond. Ré-exécutable — régénérez quand l'art ou les formes des objets changent.

Flux de travail

  1. Vérifiez le pipeline. Le modèle cible URP (UniversalAdditionalCameraData). Pour Built-in, supprimez ce bloc ; pour HDRP, utilisez HDAdditionalCameraData et désactivez le post-processing de la même manière.
  2. Copiez templates/Editor/ModelIconRenderer.cs dans un dossier/asmdef réservé à l'éditeur (référence URP runtime si vous utilisez un asmdef) et renommez l'espace de noms.
  3. Décidez du mapping des données de jeu vers les jobs : quel prefab représente chaque objet, sa taille en cellules (1×1 pour les icônes simples ; la forme de grille de l'objet pour les inventaires en grille), et le chemin de sortie. Conservez ce mapping dans le code de contenu du projet, pas dans le moteur de rendu.
  4. Appelez ModelIconRenderer.RenderBatch(jobs) depuis un élément de menu ou l'étape de construction du contenu, puis assignez les sprites résultants aux données de l'objet (AssetDatabase.LoadAssetAtPath<Sprite>(chemin)), SetDirty, SaveAssets. Les PNG sont importés en tant que sprites (l'alpha est la transparence, pas de mipmaps).
  5. Regardez chaque icône avec scripts/icon_sheet.py et corrigez les anomalies par objet (voir Boucle de révision) plutôt que de modifier les heuristiques globales.
  6. Validez les PNG via Git LFS. Ne validez pas les icônes rendues à partir d'art sous licence dans des dépôts publics.

Comment la pose est choisie

  • Modèles allongés (axe le plus long > 1,6× l'axe médian : épées, bâtons, flèches, baguettes) sont placés le long de l'axe long de l'emplacement — vertical dans les emplacements hauts, horizontal dans les larges, diagonal dans les emplacements carrés — puis pivotés de 25° autour de cet axe pour que le côté fasse face à la caméra.
  • Modèles compacts (gemmes, potions, livres, coffres) partent d'une vue 3/4 verticale, puis un balayage en lacet (−90…90), tangage (−50, −25, 0) et roulis (0…135) rend une petite sonde et conserve la vue avec le plus de pixels de silhouette. La couverture en pixels plutôt que les limites évite que des diagonales fines gagnent ; les vues de face sont pénalisées de 7 % car elles semblent plates ; la pose automatique reçoit un bonus de 10 % pour n'être remplacée que par une vue clairement meilleure.
  • Modèle compact dans un emplacement long (couverture < 30 %, emplacement ≥ 3:1) : des copies sont disposées en mosaïque le long de l'emplacement avec une légère variation de rotation/échelle (trois éclats dans un emplacement 1×3) au lieu d'un seul petit modèle.
  • Orientation : la plupart des packs (Synty inclus) créent des objets orientés +Z ; la caméra regarde le long de +Z, donc les modèles reçoivent un lacet de 180° en premier (Options.facingCorrection). Changez-le si un pack est orienté différemment.

Boucle de révision

Ne faites jamais confiance à un lot que vous n'avez pas regardé. Une feuille de contact capture ce que des centaines de lignes de log ne feront pas.

  1. Feuille : python scripts/icon_sheet.py <dossier_icônes> sheet.png --match ^Armor_ Shield --strip-prefix, puis visualisez l'image. Les icônes conservent leur rapport d'aspect, donc un objet 3×1 apparaît comme une bande, comme dans la grille.
  2. Classez chaque mauvaise icône — la correction diffère :
    • De côté / couché / dos à la caméra → posez-le avec rotationOverride. Il est appliqué comme Euler(override) * facingCorrection, donc des valeurs proches de (0,0,0) signifient "tel qu'écrit, face à la caméra" : de petites inclinaisons comme (-5, 15, 0) donnent une vue 3/4 verticale. (0, 180, 0) montre le dos. Zéro signifie "auto", donc utilisez une valeur non nulle minuscule si vous voulez exactement la pose écrite.
    • Objet plat vu de côté (bouclier, plaque, pièce) → le prefab a généralement un enfant pivoté (les prefabs d'affichage d'arme pivotent souvent le maillage de 90° sur X pour qu'il soit à plat dans le jeu). Enregistrez les localEulerAngles de l'enfant avant de deviner ; annulez-les dans l'override et ajoutez un roulis pour placer le côté long le long de l'emplacement, par ex. (0, 90, 80) pour un bouclier ovale plat dans un emplacement 3×1.
    • Mauvaise silhouette pour l'emplacement (un modèle grand et mince dans un emplacement carré : mannequins d'entraînement, supports d'armure, bannières sur poteaux) → aucune rotation ne corrige cela ; échangez le modèle.
  3. Auditionnez les modèles de remplacement en un seul rendu : pointez temporairement plusieurs objets existants vers des prefabs candidats (item.iconModel = candidat, override à zéro), rendez, faites une feuille, choisissez. Placez ensuite les gagnants dans le code de contenu — si la construction du contenu réassigne les modèles à chaque exécution, les assignations temporaires sont de toute façon écrasées.
  4. Enregistrez les poses dans le code de contenu, pas seulement sur les assets, pour qu'une reconstruction avec "écraser les données" les conserve. Appliquez une pose enregistrée uniquement lorsque l'objet n'en a pas de propre, afin que les poses réglées à la main dans l'inspecteur survivent.
  5. Re-rendez et refaites la feuille jusqu'à ce que chaque icône se lise d'un coup d'œil.

Bonnes sources de modèles pour les vêtements : les parties statiques de personnage modulaire (par ex. Synty Modular Fantasy Hero Characters_ModularParts_Static/Chr_Torso_*_Static) font de bien meilleures icônes d'armure de torse que des accessoires comme des supports d'armure ou des mannequins d'entraînement — elles remplissent un emplacement carré et se lisent immédiatement comme "armure". Les prefabs d'attachement de personnage (casques, épaulettes, capes) fonctionnent bien pour les emplacements plus petits. Les parties statiques utilisent le matériau de texture ordinaire du pack, donc elles se convertissent à votre shader comme n'importe quel accessoire.

Pièges

  • Les scènes de prévisualisation n'ont pas d'éclairage d'environnement ni de ciel — sans les lumières de remplissage et de contour, le côté éloigné de la lumière principale rend noir.
  • Le post-processing et le MSAA cassent l'alpha. Désactivez le post-traitement sur la caméra d'icône (tonemapping/bloom écrivent alpha = 1) et suréchantillonnez au lieu du MSAA.
  • Définissez cam.scene = previewScene sinon la caméra rend aussi la scène ouverte.
  • Supprimez les colliders, désactivez les Animators, les renderers de particules/trails/lignes sur l'instance — les enfants VFX et les animators de pose de liaison gonflent autrement les limites ou apparaissent comme des traînées.
  • Prémultipliez lors du sous-échantillonnage, sinon les bords transparents captent des franges sombres de la couleur de dégagement.
  • Les personnages skinnés rendent dans la pose de liaison (pose en T) ; donnez-leur un rotationOverride ou une variante de prefab posé.
  • Les modèles low-poly à textures de palette semblent gris si leurs textures de palette ont des mipmaps (voir le skill unity-asset-pack-extraction).

Fichiers

  • templates/Editor/ModelIconRenderer.cs — RenderBatch(IconJob[], Options), IconJob(model, cells, pngPath, rotationOverride), menu Tools > Icons > Render Selected Prefabs (icônes 1×1 dans un dossier Icons/ à côté de chaque prefab).
  • scripts/icon_sheet.py — feuille de contact étiquetée des icônes rendues, filtrable par nom (nécessite Pillow).

Skills associés