하하하 어느새 11번째 시간이 되었군요.
헤더파일 먼저 준비해야겠지요?
//class declare
class SVehicleMenuItem : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SVehicleMenuItem)
{}
/** Weak pointer to the parent HUD base */
SLATE_ARGUMENT(TWeakObjectPtr<AHUD>, OwnerHUD)
/** Called when the button is clicked */
SLATE_EVENT(FOnClicked, OnClicked)
/** menu item text attribute */
SLATE_ATTRIBUTE(FString, Text)
/** menu item text transparency when item is not active, optional argument */
SLATE_ARGUMENT(TOptional<float>, InactiveTextAlpha)
SLATE_END_ARGS()
이번엔 클래스 선언만 합니다. 근데 앞에 뭔가 안붙어있네요?(는 사실 다른 헤더[DeclarativeSyntaxSupport.h]에서 이미 선언된 구문들입니다.)
부모 HUD에 포인터를 가져다 놨을 때, 버튼 클릭 했을 때, 메뉴 아이템에서 텍스트 불러오는거, 활성화 되지 않은 것들 텍스트 투명화 등등을 하려고 선언했네요.
/** Needed for every widget */
void Construct(const FArguments& InArgs);
/** Says that we can support keyboard focus */
virtual bool SupportsKeyboardFocus() const override { return true; }
/** mouse button down callback */
virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
/** mouse button up callback */
virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
/** mouse move callback */
virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override;
/** sets this menu item as active (selected) */
void SetMenuItemActive(bool bIsMenuItemActive);
Construct를 정의해주는 이유는 아무래도 위젯을 만들 때 필요하기 때문이겠지요.
키보드에 포커스를 맞추는 것도 지원해주고 마우스 버튼을 눌렀을때, 안눌렀을 때도 선언해주셔야 됩니다.(메뉴 아이템들도 위젯이기때문에 마우스로 해주는게 편하겠지요) 마우스 이동 또한 되야 하니 이동 선언 해 주시고 아이템 업데이트 해야되니 SetMenuItemActive또한 선언해주시는게 좋겠지요.
protected:
/** The delegate to execute when the button is clicked */
FOnClicked OnClicked;
private:
/** menu item text attribute */
TAttribute< FString > Text;
/** getter for menu item background color */
FSlateColor GetButtonBgColor() const;
/** getter for menu item text color */
FSlateColor GetButtonTextColor() const;
/** inactive text alpha value*/
float InactiveTextAlpha;
/** active item flag */
bool bIsActiveMenuItem;
/** Pointer to our parent HUD */
TWeakObjectPtr<class AHUD> OwnerHUD;
/** style for this menu item */
const struct FVehicleMenuItemStyle *MenuItemStyle;
};
온클릭 이벤트 만들어주시고 밑에는 첫번째부터 메뉴 속성 정보를 텍스트로 나타내주려고 만든것이구요. 메뉴 항목의 배경색을 지정, 텍스트 색 지정, 텍스트의 알파값, 활성 항목 설정, 이 클래스의 부모 HUD클래스 포인터 지정, 메뉴 항목 스타일 설정 등등을 하기 위해 선언했다고 보시면 됩니다.
헤더파일은 끝이구요. 이제 C++파일입니다.(양이 얼마 안해요. 첫번째것만 하면 양이 아주 적어요.)살았어요.
void SVehicleMenuItem::Construct(const FArguments& InArgs)
{
MenuItemStyle = &FVehicleStyle::Get().GetWidgetStyle<FVehicleMenuItemStyle>("DefaultVehicleMenuItemStyle");
OwnerHUD = InArgs._OwnerHUD;
Text = InArgs._Text;
OnClicked = InArgs._OnClicked;
bIsActiveMenuItem = false;
//if attribute is set, use its value, otherwise uses default
InactiveTextAlpha = InArgs._InactiveTextAlpha.Get(1.0f);
ChildSlot
.VAlign(VAlign_Fill)
.HAlign(HAlign_Fill)
[
SNew(SOverlay)
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SBox)
.WidthOverride(374.0f)
.HeightOverride(23.0f)
[
SNew(SImage)
.Image(&MenuItemStyle->BackgroundBrush)
]
]
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SBox)
.WidthOverride(374.0f)
.HeightOverride(23.0f)
[
SNew(SImage)
.ColorAndOpacity(this,&SVehicleMenuItem::GetButtonBgColor)
.Image(&MenuItemStyle->HighlightBrush)
]
]
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Center)
.Padding(FMargin(40.0f,0,0,0))
[
SNew(STextBlock)
.TextStyle(FVehicleStyle::Get(), "VehicleGame.MenuTextStyle")
.ColorAndOpacity(this,&SVehicleMenuItem::GetButtonTextColor)
.Text(Text)
]
];
}
헤더에서 정의 했던 MenuItemStyle부터 위젯을 만들기 시작하네요. FVehicleMenuItemStyle(왠지 다음번에 이거 할 때 길거같은데...)을 불러와서 위젯스타일 기본형을 VehicleMenuItemStyle로 하네요.
그 밑에 있는 것들은 불러오기 방식이구요.(사용자가 설정한 것들로 불러오는 방식)
온클릭 이벤트를 불러와서 클릭 되면 다른 화면으로 넘어가는 역활을 만들었네요. 크기 지정한 대로 다 채우고 이미지는 불러온 스타일(맨위에서 방금 불러왔던 스타일), 슬롯을 똑같이 하나 더 만드네요.(이미지 부분만 다를 뿐.. 이미지도 사실상 SVehicleMenuItem[자기자신]이니 거의 비슷할듯. 그냥 거기에 하이라이트 하나만 덧 붙여 줬다는 것?) 슬롯을 하나 더 만들어서 이번엔 색깔을 씌우는 것을 만들어주네요.
FSlateColor SVehicleMenuItem::GetButtonTextColor() const
{
FLinearColor ResultColor;
if (bIsActiveMenuItem)
{
ResultColor = MenuItemStyle->ControlsListTableRowStyle.SelectedTextColor.GetSpecifiedColor();
}
else
{
ResultColor = MenuItemStyle->ControlsListTableRowStyle.TextColor.GetSpecifiedColor();
ResultColor.A *= InactiveTextAlpha;
}
return ResultColor;
}
FVehicleStyle은 있지만 자기 자신의 컬러와 스타일은 아직 안만들어졌으니까 만들어야겠지요. 컬러부터 만들어봅시다. 컬러는 기본 컬러로 결과를 확정 짓지만 만약 이 버튼이 액티브 된다면 결과컬러를 다른 헤더(SlateColor.h)에 선언되어있는 선택된 텍스트 컬러를 설정해SpecifiedColor로 바꿔줍니다.
만약 IsActiveMenuItem상태가 아니라면 기본 텍스트 컬러로 설정하게 되어있네요.
결과컬러를 초기화 해주구요.
FSlateColor SVehicleMenuItem::GetButtonBgColor() const
{
float BgAlpha;
const float MinAlpha = 0.7f;
const float MaxAlpha = 1.0f;
const float AnimSpeedModifier = 1.5f;
float GameTime = OwnerHUD->GetWorld()->GetRealTimeSeconds();
float AnimPercent = FMath::Abs(FMath::Sin(GameTime*AnimSpeedModifier));
if (bIsActiveMenuItem)
{
BgAlpha = FMath::Lerp(MinAlpha, MaxAlpha, AnimPercent);
}
else
{
BgAlpha = 0.0f;
}
return FLinearColor(1,1,1,BgAlpha);
}
이번엔 버튼 배경 색깔입니다.
저같았으면 랜드함수 적용해서 색깔을 좀 더 재미있게(는 불규칙 무지개) 표현하려 했을텐데 여기서는 애니메이션처럼 일정 속도로 색깔이 반짝거리게 해주는 것인가 봅니다. IsActiveMenuItem이 활성화 되어있으면 배경의 Alpha값을 조절해주고 안되어있으면 0.0f로 정의 해주고 FLinearcolor를 초기화해주네요.
FReply SVehicleMenuItem::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
//execute our "OnClicked" delegate, if we have one
if(OnClicked.IsBound() == true)
{
return OnClicked.Execute();
}
return FReply::Handled();
}
FReply SVehicleMenuItem::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
return FReply::Handled();
}
FReply SVehicleMenuItem::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent)
{
return FReply::Unhandled();
}
이번엔 마우스 버튼 관련된 것들이네요.
버튼이 눌리면(OnClicked Event) OnClicked.Excute()(온클릭은 방금 헤더에서 선언한거고 Excute()는 언리얼의 inl파일에 선언되어있음)를 실행하네요.
그 후엔 처리 이벤트를 반드시 실행해주네요. 다른 것들은 처리 이벤트를 실행하고 취소하는 것을 실행해주네요.
void SVehicleMenuItem::SetMenuItemActive(bool bIsMenuItemActive)
{
this->bIsActiveMenuItem = bIsMenuItemActive;
}
네 마지막으로 MenuItemActive시켜주는 이벤트입니다. 이렇게 하려고 SetMenuItemActive를 만들었지요.
아 이거 다 분석하려면 아직 한참 남았네...
'Development > Unreal Engine 4, 5' 카테고리의 다른 글
Third-Party Libraries - Unreal Engine 4 Documentation (0) | 2022.03.17 |
---|---|
언리얼 엔진 프로젝트에서 C++ 클래스 삭제하기 (0) | 2021.06.08 |
언리얼 경로 함수(Unreal Path Helper) (0) | 2021.06.04 |
Slate (0) | 2021.05.25 |
SButton 계열에 STextBlock 사용 시, 'FText::FText' 관련 에러 (0) | 2021.05.21 |