알겠어! TIL 수정할게.
📅 2025-11-17
언리얼 엔진의 마우스 이벤트는 두 단계로 처리된다:
OnPreviewMouseButtonDown
- 부모 → 자식 방향으로 전파 ⬇️
- 원본 이벤트 정보를 그대로 받음
- Get Effecting Button이 정확하게 동작함
OnMouseButtonDown
- 자식 → 부모 방향으로 전파 ⬆️
- 자식 위젯이 이벤트를 먼저 처리
- 이벤트 정보가 변형되거나 손상될 수 있음
Button (또는 Canvas Panel)
├─ Image
└─ TextBlock
결론: 드래그앤드롭 구현 시 OnPreviewMouseButtonDown을 사용해야 한다. 위젯 타입(Button, Canvas Panel 등)과 무관하게 자식 위젯이 있으면 Preview를 써야 한다.
OnMouseButtonDown의 반환값(true/false)이
→ OnDragDetected나 OnDrop으로 전달된다고 생각
→ 전달되지 않는다! 각 이벤트의 FPointerEvent 파라미터에서 독립적으로 확인해야 함.
OnPreviewMouseButtonDown:
Mouse Event → Get Effecting Button
→ Set CachedMouseButton (위젯 변수에 저장)
→ Branch (Left or Right?)
True: Detect Drag 반환
False: Unhandled 반환
OnDragDetected:
CachedMouseButton 사용
→ Branch (Left?)
True:
- bIsFullStack = true
- TransferQuantity = CurrentStackSize
False:
- bIsFullStack = false
- TransferQuantity = 1
→ DragOperation 생성 및 반환
OnDrop:
DragOperation → bIsFullStack 읽기
→ ServerTransferItem(..., bIsFullStack)
버튼 확인은 한 번만, 저장해서 재사용
UCLASS()
class UMyDragDropOperation : public UDragDropOperation
{
UPROPERTY(BlueprintReadWrite)
bool bIsFullStack;
UPROPERTY(BlueprintReadWrite)
int32 TransferQuantity;
};
OnPreviewMouseButtonDown (버튼 확인 및 캐싱)
↓
OnDragDetected (DragOperation에 데이터 저장)
↓
OnDrop (저장된 데이터 사용)
OnDragDetected의 Pointer Event에서 Get Effecting Button → None 반환
언리얼의 이벤트 시스템이 생각보다 복잡하다는 걸 깨달았다. 처음에는 단순히 OnMouseButtonDown에서 반환값을 조작하면 되는 줄 알았는데, 실제로는:
이 모든 것을 이해해야 제대로 동작시킬 수 있었다.
특히 OnPreviewMouseButtonDown의 존재를 몰랐다면 계속 삽질했을 것 같다. 위젯 안에 Image나 TextBlock 같은 자식 위젯이 있으면 이들이 이벤트를 먼저 받아서 버튼 정보를 망가뜨린다는 것도 직접 겪지 않았으면 상상도 못했을 문제다.
결국 프레임워크의 내부 동작 원리를 이해하는 것이 중요하다는 걸 다시 한번 배웠다. 표면적인 사용법만 아는 것과 내부 메커니즘을 이해하는 것의 차이를 체감했다.