Quick answer: Don’t Set Position in the same event that the Drag & Drop behavior is acting. Let the behavior own position, or only set it on Drop, not on Drag.

An inventory item with Drag & Drop snaps to the layout origin the instant it’s grabbed. A competing Set Position action zeroes it.

The Conflict

The Drag & Drop behavior sets the object’s position to follow the pointer. If another event also runs Set Position (e.g. “Every tick: Set position to snap_x, snap_y” with uninitialized vars), the two fight and the uninitialized one (0,0) often wins.

Let the Behavior Own Position

On DragDrop drag start:
    → (do nothing to position)

// behavior handles position automatically

While dragging, don’t touch position. The behavior does it.

Snap on Drop Only

On DragDrop drop:
    Set position to (round(Self.X / grid) * grid, round(Self.Y / grid) * grid)

Snap-to-grid happens once, on drop — not every frame.

Grab-Point Offset

If the object jumps so the pointer is at its origin (top-left) instead of where you grabbed, record the offset on drag start and re-apply — or set the object’s origin to its center.

Verifying

Grab an inventory item anywhere on it; it follows the pointer from that grab point. On drop, it snaps to the grid cell. No teleport to origin.

“Behaviors and manual Set Position fight. Pick one owner of position per state.”

For polished inventory UX, add a small Tween on drop to the snapped cell — the item glides into place instead of popping.