쾌락없는 책임 (공부)/Unreal

[Unreal] Unreal ToolTip, 툴팁 추가해보기

허스크 2023. 5. 24. 16:18
반응형

개요

위 사진처럼 특정 아이콘에 마우스를 가져다 대면 간단한 설명 창이 하나 나오게 됩니다. 이런 것들을 보통 'ToolTip - 툴팁'이라고 합니다. 이런 기능을 언리얼에서 대부분 할 수 있게 준비를 해 주는데 이번에 이 ToolTip을 어떻게 만드는지 간단하게 메모해 두려고 합니다. 제가 까먹을까 봐요

 

 

ToolTip 은 어디서 볼 수 있는가?

위 화면은 저의 인벤토리 슬롯의 버튼의 Detail창입니다. 이곳에서 Behavior 창을 보시면 Advanced > Tool Tip Widget을 보실 수 있는데 여기서 BP를 통해 세팅할 수 있게 되어 있습니다.

Tool Tip Widget에서 오른쪽 'Bind' 버튼을 눌러 Create... 를 하면 이런 BP 함수가 만들어지는 것을 볼 수 있습니다. 이 경우 저 'Return Value'에 ToolTip으로 올라갈 Widget을 넘겨주면 툴팁이 나오는 것인데, 저는 C++로 제작을 했기 때문에 아래 코드에서 보여드리겠습니다.

 

 

C++로 Unreal Tool Tip 바인딩하기

일단 저의 간단한 이미지, 이름, 설명이 있는 ToolTip 구성입니다.

class PROJECTFA_API UItemTooltipWidget : public UUserWidget
{
	GENERATED_BODY()

public:
	UPROPERTY(BlueprintReadWrite, meta=(BindWidget))
	TObjectPtr<UImage> ItemImage;
	UPROPERTY(BlueprintReadWrite, meta=(BindWidget))
	TObjectPtr<UTextBlock> ItemName;
	UPROPERTY(BlueprintReadWrite, meta=(BindWidget))
	TObjectPtr<UMultiLineEditableText> ItemDescription;
};

그리고 아래 코드가 인벤토리에서 각 칸을 나타낼 위젯 코드입니다. 

class PROJECTFA_API UInventorySlotWidget : public UUserWidget
{
	GENERATED_BODY()

//... 이 인벤토리 슬롯을 구성하는 여러 요소들 정의

private
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
	TSubclassOf<UItemTooltipWidget> InventoryToolTipClass;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta = (AllowPrivateAccess = "true"))
	TObjectPtr<UItemTooltipWidget> InventoryToolTipWidget;

protected:
	virtual void NativeConstruct() override;
    
private:
	void SetToolTipWidget();
};

툴팁 구성요소들만 남겨뒀는데 위 코드에서 아래의 일을 할 예정입니다.

  • NativeConstruct에서 SetToolTipWidget을 호출
  • SetToolTipWidget에서 InventoryToolTipClass를 통해서 ToolTipWidget을 생성할 것임
  • 이후 SetToolTip 함수를 통해서 툴팁을 설정할 예정

그럼 사실상 SetToolTipWidget 함수가 결정적입니다.

void UInventorySlotWidget::NativeConstruct()
{
	Super::NativeConstruct();

	SetToolTipWidget();
}

void UInventorySlotWidget::SetToolTipWidget()
{
	// 여기서 생성을 함
	if(InventoryToolTipClass == nullptr)	return;
	InventoryToolTipWidget = CreateWidget<UItemTooltipWidget>(this, InventoryToolTipClass);
	if(InventoryToolTipWidget == nullptr)	return;
    
	if(const auto Item = SlotItem.Get())
	{
		// 아이템 정보에 따라 툴팁 위젯의 텍스트, 이미지 등을 설정
	}
    
    // 이후 버튼의 SetToolTip 함수에 만들어둔 툴팁 위젯을 넘겨줌!
	ItemButton->SetToolTip(InventoryToolTipWidget);
}

이렇게 되면 ToolTip을 잘 확인할 수 있을 것입니다.

 

이런 느낌으로 잘 보일 것입니다.

 

 

툴팁이 델리게이트로 바인딩은 안될까?

저 같은 경우 처음 BP를 통해서 ToolTip을 먼저 제작한 후 C++로 이전 작업을 했습니다. 그래서 'BP에서 함수 바인딩을 했으니 C++에서도 그래야겠지?' 하고 아래 코드처럼 했습니다.

void UInventorySlotWidget::NativeConstruct()
{
	Super::NativeConstruct();

	InventoryToolTipWidget = CreateWidget<UItemTooltipWidget>(this, InventoryToolTipClass);
	ItemButton->ToolTipWidgetDelegate.BindUFunction(this, FName("TooltipWidgetPopup"));
}

UUserWidget* UInventorySlotWidget::TooltipWidgetPopup()
{
	if(InventoryToolTipWidget == nullptr)	return nullptr;
	if(const auto Item = SlotItem.Get())
	{
		//... 툴팁 위젯의 텍스트, 이미지 등을 설정
	}
	return InventoryToolTipWidget;
}

그런데 이렇게 한 경우 제대로 바인딩이 되지 않는 사실을 알게 되었습니다. 이때의 코드가 버전관리에 남아있지 않아서 다시 오류 추적이 불가능하지만...

 

일단 ToolTipWidgetDelegate라는 변수에 바인딩할 수는 있다는 사실을 알려드린 겁니다... 이걸 제대로 사용하실 수 있는 분들은 시간 나실 때 댓글로 남겨주시면 한번 시도해 보겠습니다.

반응형