The stash panel
One widget that draws a container from the platform, using your own item art.
Drop it in
Search the palette for Raid State Stash Panel and put it anywhere a widget can go. The entire tree is built in C++ — grid, tiles, art, counts — so there is no Blueprint to wire up and no widget you have to name correctly for it to find. A component that expects a CanvasPanel called StashCanvas works perfectly until somebody types StashCanvasPanel, and then it fails silently and looks like our bug.
Where the art comes from
Your DataTable, matched by item_id. The icon column is found tolerantly — Item Icon, Icon, Thumbnail and Image all work, as a soft or hard reference. An item with no icon draws its identifier rather than an empty square, so you can see which row is missing art instead of wondering whether the widget is broken.
Moving items
The panel exposes the operations and lets your UI decide what a click means:
Deposit Item (ItemId, Quantity, X, Y, SourceSlot)
-> On Deposited (ItemId, Quantity, SourceSlot)
Withdraw Instance (Instance)
-> On Withdrawn (Instance)
Transfer From (SourcePanel, Instance, X, Y)
-> On Transferred (Instance)Plus two hit tests for a UI that follows the mouse: Cell At Screen Position and Instance At Screen Position. The second tests the whole footprint rather than the origin, because a player clicking any cell of a rifle means that rifle.
The order matters
The platform is changed first, and your game changes only once it has succeeded. On Deposited fires after the server holds the item — until then the character keeps it, so a failed deposit costs nothing. The alternative, taking it locally then pushing, loses the item outright when the push fails.
The cost is that a crash in the gap leaves a duplicate rather than a hole. That is the right way round: a duplicate is visible and correctable on the next sync, and a player who lost a rifle to a dropped packet is a player who stops trusting the game.
Transfer, not withdraw-then-deposit
Moving between two panels — a loadout and a stash, say — is a single move on the server. Two calls would leave the item nowhere at all if the second failed, and unlike the in-raid path there is no game inventory holding it in between to fall back on.
If clicking does nothing
- Visibility. A UserWidget is
SelfHitTestInvisibleby default and never receives clicks — only its children do. - Layout mismatch. A slots panel pointed at a grid container draws what it actually received and says so in its status line, rather than pretending.