Ícones de itens renderizados a partir de modelos 3D
Transforme os próprios prefabs do seu jogo em sprites de ícones consistentes a partir de código: uma cena de pré-visualização isolada, uma câmera ortográfica com três luzes direcionais, uma pose escolhida por modelo, uma renderização com supersampling 2×, downsampling pré-multiplicado e um contorno escuro para que os ícones sejam legíveis em qualquer fundo. Rerunável — regenere sempre que a arte ou as formas dos itens mudarem.
Fluxo de trabalho
- Verifique o pipeline. O template tem como alvo a URP (
UniversalAdditionalCameraData). Para Built-in, remova esse bloco; para HDRP, useHDAdditionalCameraDatae desabilite o pós-processamento da mesma forma. - Copie
templates/Editor/ModelIconRenderer.cspara uma pasta/asmdef somente editor (faz referência ao runtime da URP se estiver usando um asmdef) e renomeie o namespace. - Defina o mapeamento dos dados do jogo para os trabalhos: qual prefab representa cada item, sua ocupação em células (1×1 para ícones comuns; a forma de grade do item para inventários em grade) e o caminho de saída. Mantenha esse mapeamento no código de conteúdo do projeto, não no renderizador.
- Chame
ModelIconRenderer.RenderBatch(jobs)a partir de um item de menu ou da etapa de build de conteúdo, depois atribua os sprites resultantes aos dados do item (AssetDatabase.LoadAssetAtPath<Sprite>(path)),SetDirty,SaveAssets. Os PNGs são importados como sprites (alfa é transparência, sem mipmaps). - Olhe para cada ícone com
scripts/icon_sheet.pye corrija os outliers por item (veja Ciclo de revisão) em vez de ajustar as heurísticas globais. - Envie os PNGs via Git LFS. Não envie ícones renderizados a partir de arte licenciada para repositórios públicos.
Como a pose é escolhida
- Modelos alongados (eixo mais longo > 1,6× o eixo médio: espadas, cajados, flechas, varinhas) são colocados ao longo do eixo longo do slot — vertical em slots altos, horizontal em slots largos, diagonal em slots quadrados — depois girados 25° em torno desse eixo para que a lateral fique voltada para a câmera.
- Modelos compactos (gemas, poções, livros, baús) começam a partir de uma visão 3/4 ereta, então uma varredura de guinada (−90…90), inclinação (−50, −25, 0) e rotação (0…135) renderiza uma pequena sonda e mantém a vista com o maior número de pixels de silhueta. A cobertura de pixels em vez de limites evita que diagonais finas vençam; vistas frontais são penalizadas em 7% porque parecem planas; a pose automática recebe um bônus de 10% para que seja substituída apenas por uma vista claramente melhor.
- Modelo compacto em um slot longo (cobertura < 30%, slot ≥ 3:1): cópias são dispostas ao longo do slot com pequena variação de rotação/escala (três fragmentos em um slot 1×3) em vez de um único modelo minúsculo.
- Orientação: a maioria dos packs (incluindo Synty) cria props voltados para +Z; a câmera olha ao longo de +Z, então os modelos recebem um giro de 180° primeiro (
Options.facingCorrection). Altere se um pack estiver voltado para outra direção.
Ciclo de revisão
Nunca confie em um lote que você não tenha visto. Uma folha de contato captura o que centenas de linhas de log não capturam.
- Folha de contato:
python scripts/icon_sheet.py <pasta_de_icones> sheet.png --match ^Armor_ Shield --strip-prefix, depois visualize a imagem. Os ícones mantêm sua proporção original, então um item 3×1 aparece como uma faixa, como ficará na grade. - Classifique cada ícone ruim — a correção difere:
- De lado / deitado / de costas para a câmera → posicione-o com
rotationOverride. É aplicado comoEuler(override) * facingCorrection, então valores próximos a(0,0,0)significam "como criado, voltado para a câmera": pequenas inclinações como(-5, 15, 0)fornecem uma visão 3/4 ereta.(0, 180, 0)mostra a parte de trás. Zero significa "automático", portanto use um valor pequeno diferente de zero se quiser exatamente a pose criada. - Coisa plana de perfil (escudo, placa, moeda) → o prefab geralmente tem um filho rotacionado (prefabs de exibição de arma frequentemente rotacionam a malha 90° em X para que fique plana no jogo). Registre os
localEulerAnglesdo filho antes de adivinhar; cancele-os no override e adicione uma rotação para colocar o lado longo ao longo do slot, ex.:(0, 90, 80)para um escudo oval plano em um slot 3×1. - Silhueta errada para o slot (um modelo alto e fino em um slot quadrado: bonecos de treino, suportes de armadura, estandartes em postes) → nenhuma rotação corrige isso; troque o modelo.
- De lado / deitado / de costas para a câmera → posicione-o com
- Teste modelos substitutos em uma única renderização: aponte temporariamente vários itens existentes para prefabs candidatos (
item.iconModel = candidato, override zero), renderize, folha de contato, escolha. Depois coloque os vencedores no código de conteúdo — se o build de conteúdo reatribuir modelos a cada execução, as atribuições temporárias serão sobrescritas de qualquer forma. - Registre as poses no código de conteúdo, não apenas nos assets, para que uma reconstrução com "sobrescrever dados" as mantenha. Aplique uma pose registrada apenas quando o item não tiver pose própria, para que poses ajustadas manualmente no Inspector sobrevivam.
- Re-renderize e refaça a folha de contato até que cada ícone seja compreendido de relance.
Boas fontes de modelo para vestíveis: partes modulares estáticas de personagens (ex.: Synty Modular Fantasy Hero Characters_ModularParts_Static/Chr_Torso_*_Static) fazem ícones de armadura de peito muito melhores do que props como suportes de armadura ou bonecos de treino — eles preenchem um slot quadrado e são imediatamente reconhecidos como "armadura". Prefabs de anexos de personagem (capacetes, ombreiras, capas) funcionam bem para slots menores. As partes estáticas usam o material de textura comum do pack, então convertem para seu shader como qualquer prop.
Armadilhas
- Cenas de pré-visualização não têm iluminação ambiente ou skybox — sem as luzes de preenchimento e de borda, o lado oposto à luz principal renderiza em preto.
- Pós-processamento e MSAA quebram o alfa. Desabilite o pós-processamento na câmera de ícones (mapeamento de tom/bloom escrevem alfa = 1) e use supersampling em vez de MSAA.
- Defina
cam.scene = previewSceneou a câmera também renderizará a cena aberta. - Remova colisores, desabilite Animators, renderizadores de partículas/trilhas/linhas na instância — filhos VFX e animadores de pose de ligação podem inflar os limites ou aparecer como borrões.
- Pré-multiplique ao fazer downsampling, ou bordas transparentes pegarão franjas escuras da cor de limpeza.
- Personagens com esqueleto renderizam em pose de ligação (pose T); dê a eles um
rotationOverrideou uma variante de prefab posada. - Modelos low-poly com texturas de paleta parecem cinza se suas texturas de paleta tiverem mipmaps (veja a skill
unity-asset-pack-extraction).
Arquivos
templates/Editor/ModelIconRenderer.cs-RenderBatch(IconJob[], Options),IconJob(model, cells, pngPath, rotationOverride), menu Tools > Icons > Render Selected Prefabs (ícones 1×1 em uma pastaIcons/ao lado de cada prefab).scripts/icon_sheet.py- folha de contato legendada dos ícones renderizados, filtrável por nome (requer Pillow).