3D 모델에서 렌더링된 아이템 아이콘
게임 자체 프리팹을 코드로 일관된 아이콘 스프라이트로 변환합니다: 격리된 프리뷰 씬, 세 방향 조명이 있는 직교 카메라, 모델별로 선택된 포즈, 2배 슈퍼샘플링 렌더링, 프리멀티플라이다운샘플, 그리고 모든 배경에서 읽을 수 있도록 어두운 아웃라인을 적용합니다. 재실행 가능 - 아트나 아이템 모양이 바뀌면 언제든 재생성할 수 있습니다.
워크플로우
- 파이프라인을 확인하세요. 템플릿은 URP(
UniversalAdditionalCameraData)를 대상으로 합니다. Built-in 파이프라인을 사용한다면 해당 블록을 삭제하세요. HDRP의 경우HDAdditionalCameraData를 사용하고 같은 방식으로 후처리를 비활성화하세요. templates/Editor/ModelIconRenderer.cs를 복사하여 에디터 전용 폴더/asmdef에 넣고(asmdef를 사용하면 URP 런타임을 참조해야 함) 네임스페이스를 변경하세요.- 게임 데이터에서 작업으로의 매핑을 결정하세요: 각 아이템을 나타내는 프리팹, 셀 크기(일반 아이콘은 1×1, 그리드 인벤토리는 아이템의 그리드 모양), 출력 경로. 해당 매핑은 렌더러가 아닌 프로젝트의 컨텐츠 코드에 유지하세요.
- 메뉴 항목이나 컨텐츠 빌드 단계에서
ModelIconRenderer.RenderBatch(jobs)를 호출한 다음, 결과 스프라이트를 아이템 데이터에 할당하고(AssetDatabase.LoadAssetAtPath<Sprite>(path)),SetDirty,SaveAssets를 실행하세요. PNG는 스프라이트로 임포트됩니다(알파는 투명도, 밉맵 없음). scripts/icon_sheet.py로 모든 아이콘을 확인하고, 전역 휴리스틱을 조정하는 대신 아이템별로 이상치를 수정하세요(리뷰 루프 참조).- PNG를 Git LFS로 커밋하세요. 라이선스 아트에서 렌더링된 아이콘을 공개 리포지토리에 커밋하지 마세요.
포즈가 선택되는 방식
- 길쭉한 모델(가장 긴 축이 중간 축보다 1.6배 이상: 검, 지팡이, 화살, 완드)은 슬롯의 긴 축을 따라 배치됩니다 - 높은 슬롯에서는 수직, 넓은 슬롯에서는 수평, 정사각형 슬롯에서는 대각선으로 배치된 후, 해당 축을 중심으로 25° 회전하여 측면이 카메라를 향하게 합니다.
- 컴팩트한 모델(보석, 물약, 책, 상자)은 직립 3/4 뷰에서 시작하여 요(yaw: −90…90), 피치(pitch: −50, −25, 0), 롤(roll: 0…135) 스윕으로 작은 프로브를 렌더링하고 가장 많은 실루엣 픽셀을 제공하는 뷰를 유지합니다. 경계 상자 대신 픽셀 범위를 사용하면 얇은 대각선이 우선되지 않습니다. 정면 뷰는 평면적으로 보이기 때문에 7% 패널티가 적용됩니다. 자동 포즈는 10% 보너스를 받아 명확히 더 나은 뷰가 있을 때만 교체됩니다.
- 긴 슬롯의 컴팩트 모델(커버리지 < 30%, 슬롯 종횡비 ≥ 3:1): 하나의 작은 모델 대신 약간의 회전/크기 변화를 주어 슬롯을 따라 복사본이 타일링됩니다(1×3 슬롯에 세 개의 조각).
- 방향: 대부분의 팩(Synty 포함)은 소품이 +Z 방향을 향하도록 제작합니다. 카메라는 +Z 방향을 바라보므로 모델은 먼저 180° 요(yaw)가 적용됩니다(
Options.facingCorrection). 다른 팩이 다른 방향을 향한다면 변경하세요.
리뷰 루프
확인하지 않은 배치를 절대 믿지 마세요. 하나의 시트가 수백 줄의 로그보다 더 많은 것을 알려줍니다.
- 시트:
python scripts/icon_sheet.py <icon_folder> sheet.png --match ^Armor_ Shield --strip-prefix, 그런 다음 이미지를 보세요. 아이콘은 종횡비를 유지하므로 3×1 아이템은 그리드에서와 마찬가지로 스트립으로 표시됩니다. - 각 잘못된 아이콘을 분류하세요 - 수정 방법이 다릅니다:
- 옆으로/누워서/뒤를 향함 →
rotationOverride로 포즈를 지정하세요.Euler(override) * facingCorrection으로 적용되므로(0,0,0)에 가까운 값은 "제작된 대로, 카메라를 향함"을 의미합니다. 작은 기울기(예:(-5, 15, 0))는 직립 3/4 뷰를 제공합니다.(0, 180, 0)은 뒷면을 보여줍니다. 0은 자동을 의미하므로, 제작된 포즈를 정확히 원한다면 아주 작은 0이 아닌 값을 사용하세요. - 엣지 방향의 평평한 물체(방패, 판, 동전) → 프리팹에 보통 회전된 자식이 있습니다(무기 표시 프리팹은 종종 메시를 X축으로 90° 회전시켜 게임에서 평평하게 보이게 함). 추측하기 전에 자식의
localEulerAngles를 로그로 확인하세요. 오버라이드에서 이를 취소하고 긴 쪽이 슬롯을 따라 놓이도록 롤을 추가하세요(예: 3×1 슬롯의 평평한 타원형 방패는(0, 90, 80)). - 슬롯에 맞지 않는 실루엣(정사각형 슬롯의 길고 가는 모델: 훈련용 허수아비, 갑옷 거치대, 깃대의 깃발 등) → 어떤 회전도 고칠 수 없습니다. 모델을 교체하세요.
- 옆으로/누워서/뒤를 향함 →
- 한 번의 렌더링으로 대체 모델을 청취: 여러 기존 아이템을 임시로 후보 프리팹에 지정하고(
item.iconModel = candidate, 오버라이드 0), 렌더링하고, 시트를 보고, 선택하세요. 그런 다음 승자를 컨텐츠 코드에 넣으세요 - 컨텐츠 빌드가 매 실행마다 모델을 다시 할당한다면 임시 할당은 덮어쓰여집니다. - 포즈를 에셋뿐만 아니라 컨텐츠 코드에도 기록하여 "데이터 덮어쓰기"로 재빌드해도 유지되도록 하세요. 아이템에 자체 포즈가 없을 때만 기록된 포즈를 적용하여, 인스펙터에서 수동으로 조정된 포즈가 유지되도록 하세요.
- 모든 아이콘이 한눈에 읽힐 때까지 재렌더링하고 시트를 다시 만드세요.
착용 가능 아이템의 좋은 모델 소스: 정적 모듈러 캐릭터 파트(예: Synty Modular Fantasy Hero의 Characters_ModularParts_Static/Chr_Torso_*_Static)는 갑옷 거치대나 훈련용 허수아비 같은 소품보다 훨씬 더 좋은 가슴 방어구 아이콘을 만듭니다 - 정사각형 슬롯을 채우고 즉시 "방어구"로 읽힙니다. 캐릭터 부착 프리팹(투구, 어깨 패드, 망토)은 더 작은 슬롯에 잘 작동합니다. 정적 파트는 팩의 일반 텍스처 재질을 사용하므로 다른 소품처럼 셰이더로 변환됩니다.
주의사항
- 프리뷰 씬에는 환경 조명이나 스카이박스가 없습니다 - 필라이트와 림라이트가 없으면 메인 라이트에서 멀어진 쪽이 검게 렌더링됩니다.
- 후처리와 MSAA는 알파를 깨뜨립니다. 아이콘 카메라에서 후처리를 비활성화하고(톤매핑/블룸이 알파를 1로 기록함) MSAA 대신 슈퍼샘플링을 사용하세요.
cam.scene = previewScene을 설정하지 않으면 카메라가 열린 씬도 함께 렌더링합니다.- 인스턴스에서 콜라이더를 제거하고, 애니메이터, 파티클/트레일/라인 렌더러를 비활성화하세요 - VFX 자식과 바인드 포즈 애니메이터는 경계를 부풀리거나 번짐 현상을 일으킵니다.
- 다운샘플링 시 프리멀티플라이를 사용하지 않으면 투명 가장자리가 클리어 컬러로 인해 어두운 프린지가 생깁니다.
- 스킨드 캐릭터는 바인드 포즈(T-포즈)로 렌더링됩니다.
rotationOverride를 주거나 포즈가 적용된 프리팹 변형을 사용하세요. - 팔레트 텍스처를 사용하는 저폴리 모델은 팔레트 텍스처에 밉맵이 있으면 회색으로 보입니다(
unity-asset-pack-extraction스킬 참조).
파일
templates/Editor/ModelIconRenderer.cs-RenderBatch(IconJob[], Options),IconJob(model, cells, pngPath, rotationOverride), 메뉴 Tools > Icons > Render Selected Prefabs(각 프리팹 옆Icons/폴더에 1×1 아이콘 생성).scripts/icon_sheet.py- 렌더링된 아이콘의 레이블이 있는 콘택트 시트, 이름으로 필터링 가능(Pillow 필요).