Transmission #010: Runtime Inventory Icons

With buildings and terrain working (Transmission #009), we shifted focus to the inventory system. Every item had a hand-assigned icon sprite on the ScriptableObject, which meant any new weapon, consumable, or piece of equipment needed someone to render an icon manually. We replaced all of that with a system that generates icons from the item’s 3D prefab at runtime.

How it works now

A static utility class, InventoryIconFromPrefab, handles the whole pipeline. When the inventory UI asks for an icon (GetIcon(definition)), the system checks a cache first. On a miss it enqueues the item and, at the end of the frame, instantiates the item’s prefab off-screen (at world position 10000, 0, 0), points a dedicated orthographic camera at it, calls Camera.Render(), reads back the pixels into a Texture2D, and creates a Sprite from that. The sprite goes into the cache so subsequent frames return instantly. All generation happens inside a coroutine that waits for WaitForEndOfFrame() so the URP render pass is valid when the camera fires.

For equipment, the system uses equippedPrefab (the same prefab that appears on the character). For every other item type, we added a new displayPrefab field on the base ItemDefinition so you can assign any mesh and get an icon for free. The old icon sprite field is gone – no more manual icon art.

What changed in the UI

Both InventorySlotUI and EquipmentSlotUI now call InventoryIconFromPrefab.GetIcon() instead of reading definition.icon. Since icon generation is deferred (first call returns null, icon arrives next frame), InventoryPanelUI subscribes to InventoryIconFromPrefab.OnIconsGenerated and does a full refresh when new icons land. The result is that every slot populates itself automatically the first time you open the inventory, with no per-item setup needed beyond assigning a prefab.

Camera settings

We also adjusted the scene camera – third-person offset moved to (0, 0, -8) and pitch locked to 90° for a top-down view during map testing – and changed the directional light from pure black to a warm tone so the terrain and buildings are actually visible.

Scene template

The main scene got saved as a SceneTemplate (MainTemplate.scenetemplate) so new scenes start with all the current GameObjects, prefab references, and component settings already in place. No more manually re-adding the player, map chunks, HUD, and mobile controls every time.