Improve attribute menu visual style

This commit is contained in:
2026-04-26 21:29:17 +08:00
parent baeb4098c9
commit 8a29b6eeb7
14 changed files with 438 additions and 114 deletions

View File

@@ -9,11 +9,33 @@
#include "Components/TextBlock.h" #include "Components/TextBlock.h"
#include "Components/VerticalBox.h" #include "Components/VerticalBox.h"
#include "Components/VerticalBoxSlot.h" #include "Components/VerticalBoxSlot.h"
#include "Engine/Texture2D.h"
#include "Fonts/SlateFontInfo.h" #include "Fonts/SlateFontInfo.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
#include "Styling/SlateBrush.h"
#include "UI/PHYAttributeRowWidget.h" #include "UI/PHYAttributeRowWidget.h"
#include "Widgets/SWidget.h" #include "Widgets/SWidget.h"
namespace
{
const TCHAR* const AttributeGroupPaperTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_PaperPanel.T_PHY_UI_PaperPanel");
const TCHAR* const AttributeGroupGoldRuleTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_GoldRule.T_PHY_UI_GoldRule");
FSlateBrush MakeAttributeGroupBrush(const TCHAR* TexturePath, const FVector2D ImageSize, const FLinearColor Tint, const ESlateBrushDrawType::Type DrawAs = ESlateBrushDrawType::Box, const FMargin Margin = FMargin(0.08f))
{
FSlateBrush Brush;
Brush.DrawAs = DrawAs;
Brush.Margin = Margin;
Brush.ImageSize = ImageSize;
Brush.TintColor = FSlateColor(Tint);
if (UTexture2D* Texture = LoadObject<UTexture2D>(nullptr, TexturePath))
{
Brush.SetResourceObject(Texture);
}
return Brush;
}
}
UPHYAttributeGroupWidget::UPHYAttributeGroupWidget(const FObjectInitializer& ObjectInitializer) UPHYAttributeGroupWidget::UPHYAttributeGroupWidget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
{ {
@@ -58,7 +80,7 @@ UPHYAttributeRowWidget* UPHYAttributeGroupWidget::AddRow(FText Label, FText Valu
RowWidget->SetRow(MoveTemp(Label), MoveTemp(Value), bCanUpgrade); RowWidget->SetRow(MoveTemp(Label), MoveTemp(Value), bCanUpgrade);
if (UVerticalBoxSlot* RowSlot = RowsBox->AddChildToVerticalBox(RowWidget)) if (UVerticalBoxSlot* RowSlot = RowsBox->AddChildToVerticalBox(RowWidget))
{ {
RowSlot->SetPadding(FMargin(0.0f, 1.0f)); RowSlot->SetPadding(FMargin(0.0f, 2.0f));
} }
return RowWidget; return RowWidget;
} }
@@ -76,7 +98,7 @@ void UPHYAttributeGroupWidget::BuildNativeWidgetTree()
} }
UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RootBorder")); UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RootBorder"));
RootBorder->SetBrushColor(FLinearColor(0.98f, 0.94f, 0.84f, 0.58f)); RootBorder->SetBrush(MakeAttributeGroupBrush(AttributeGroupPaperTexturePath, FVector2D(500.0f, 260.0f), FLinearColor(0.99f, 0.97f, 0.89f, 0.76f), ESlateBrushDrawType::Box, FMargin(0.045f)));
RootBorder->SetPadding(FMargin(14.0f, 10.0f)); RootBorder->SetPadding(FMargin(14.0f, 10.0f));
WidgetTree->RootWidget = RootBorder; WidgetTree->RootWidget = RootBorder;
@@ -84,11 +106,18 @@ void UPHYAttributeGroupWidget::BuildNativeWidgetTree()
RootBorder->SetContent(RootBox); RootBorder->SetContent(RootBox);
TitleText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("TitleText")); TitleText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("TitleText"));
TitleText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 17)); TitleText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 19));
TitleText->SetColorAndOpacity(FSlateColor(FLinearColor(0.56f, 0.18f, 0.10f, 1.0f))); TitleText->SetColorAndOpacity(FSlateColor(FLinearColor(0.48f, 0.27f, 0.11f, 1.0f)));
if (UVerticalBoxSlot* TitleSlot = RootBox->AddChildToVerticalBox(TitleText)) if (UVerticalBoxSlot* TitleSlot = RootBox->AddChildToVerticalBox(TitleText))
{ {
TitleSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 6.0f)); TitleSlot->SetPadding(FMargin(2.0f, 0.0f, 0.0f, 2.0f));
}
UBorder* HeaderRule = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("HeaderRule"));
HeaderRule->SetBrush(MakeAttributeGroupBrush(AttributeGroupGoldRuleTexturePath, FVector2D(512.0f, 24.0f), FLinearColor(0.87f, 0.69f, 0.34f, 0.72f), ESlateBrushDrawType::Image, FMargin(0.0f)));
if (UVerticalBoxSlot* RuleSlot = RootBox->AddChildToVerticalBox(HeaderRule))
{
RuleSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 8.0f));
} }
RowsBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("RowsBox")); RowsBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("RowsBox"));

View File

@@ -11,18 +11,26 @@
#include "Blueprint/WidgetTree.h" #include "Blueprint/WidgetTree.h"
#include "Components/Border.h" #include "Components/Border.h"
#include "Components/Button.h" #include "Components/Button.h"
#include "Components/CanvasPanel.h"
#include "Components/CanvasPanelSlot.h"
#include "Components/HorizontalBox.h" #include "Components/HorizontalBox.h"
#include "Components/HorizontalBoxSlot.h" #include "Components/HorizontalBoxSlot.h"
#include "Components/SafeZone.h" #include "Components/SafeZone.h"
#include "Components/ScaleBox.h"
#include "Components/SizeBox.h" #include "Components/SizeBox.h"
#include "Components/Spacer.h"
#include "Components/TextBlock.h" #include "Components/TextBlock.h"
#include "Components/VerticalBox.h" #include "Components/VerticalBox.h"
#include "Components/VerticalBoxSlot.h" #include "Components/VerticalBoxSlot.h"
#include "Components/WidgetSwitcher.h" #include "Components/WidgetSwitcher.h"
#include "Engine/Texture2D.h"
#include "Fonts/SlateFontInfo.h" #include "Fonts/SlateFontInfo.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#include "Player/PHYPlayerState.h" #include "Player/PHYPlayerState.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
#include "Styling/SlateBrush.h"
#include "Styling/SlateTypes.h"
#include "UI/PHYAttributeResourceBarWidget.h"
#include "UI/PHYAttributeOverviewPageWidget.h" #include "UI/PHYAttributeOverviewPageWidget.h"
#include "UI/PHYAttributeSummaryWidget.h" #include "UI/PHYAttributeSummaryWidget.h"
#include "UI/PHYCombatDerivedAttributePageWidget.h" #include "UI/PHYCombatDerivedAttributePageWidget.h"
@@ -31,6 +39,93 @@
namespace namespace
{ {
constexpr float AttributeDesignWidth = 1693.0f;
constexpr float AttributeDesignHeight = 942.0f;
const TCHAR* const AttributePaperTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_PaperPanel.T_PHY_UI_PaperPanel");
const TCHAR* const AttributeJadeTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_JadePanel.T_PHY_UI_JadePanel");
const TCHAR* const AttributeCinnabarTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_CinnabarTab.T_PHY_UI_CinnabarTab");
const TCHAR* const AttributeGoldRuleTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_GoldRule.T_PHY_UI_GoldRule");
FSlateBrush MakeAttributeMenuBrush(const TCHAR* TexturePath, const FVector2D ImageSize, const FLinearColor Tint, const ESlateBrushDrawType::Type DrawAs = ESlateBrushDrawType::Box, const FMargin Margin = FMargin(0.08f))
{
FSlateBrush Brush;
Brush.DrawAs = DrawAs;
Brush.Margin = Margin;
Brush.ImageSize = ImageSize;
Brush.TintColor = FSlateColor(Tint);
if (UTexture2D* Texture = LoadObject<UTexture2D>(nullptr, TexturePath))
{
Brush.SetResourceObject(Texture);
}
return Brush;
}
void AddAttributeMenuCanvasChild(UCanvasPanel* CanvasPanel, UWidget* ChildWidget, const FVector2D Position, const FVector2D Size, const int32 ZOrder = 0)
{
if (!CanvasPanel || !ChildWidget)
{
return;
}
if (UCanvasPanelSlot* CanvasSlot = CanvasPanel->AddChildToCanvas(ChildWidget))
{
CanvasSlot->SetAutoSize(false);
CanvasSlot->SetPosition(Position);
CanvasSlot->SetSize(Size);
CanvasSlot->SetZOrder(ZOrder);
}
}
UTextBlock* CreateAttributeMenuText(UWidgetTree* WidgetTree, const FName WidgetName, const FText Text, const int32 FontSize, const FLinearColor Color)
{
UTextBlock* TextBlock = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), WidgetName);
TextBlock->SetText(Text);
TextBlock->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), FontSize));
TextBlock->SetColorAndOpacity(FSlateColor(Color));
return TextBlock;
}
UButton* CreateAttributeNavButton(UWidgetTree* WidgetTree, const FName WidgetName, const FText Label, const bool bActive)
{
UButton* Button = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), WidgetName);
const FLinearColor NormalTint = bActive ? FLinearColor(1.0f, 0.95f, 0.82f, 0.98f) : FLinearColor(0.95f, 0.91f, 0.80f, 0.30f);
const FLinearColor HoverTint = bActive ? FLinearColor(1.0f, 0.98f, 0.88f, 1.0f) : FLinearColor(0.40f, 0.58f, 0.50f, 0.42f);
FButtonStyle ButtonStyle;
ButtonStyle.SetNormal(MakeAttributeMenuBrush(AttributePaperTexturePath, FVector2D(180.0f, 72.0f), NormalTint));
ButtonStyle.SetHovered(MakeAttributeMenuBrush(AttributePaperTexturePath, FVector2D(180.0f, 72.0f), HoverTint));
ButtonStyle.SetPressed(MakeAttributeMenuBrush(AttributeCinnabarTexturePath, FVector2D(180.0f, 72.0f), FLinearColor(0.72f, 0.25f, 0.14f, 0.95f)));
Button->SetStyle(ButtonStyle);
UTextBlock* ButtonText = CreateAttributeMenuText(WidgetTree, NAME_None, Label, 24, bActive ? FLinearColor(0.04f, 0.44f, 0.38f, 1.0f) : FLinearColor(0.30f, 0.28f, 0.22f, 1.0f));
Button->SetContent(ButtonText);
return Button;
}
void ApplyAttributeSubTabStyle(UButton* Button, const bool bActive)
{
if (!Button)
{
return;
}
FButtonStyle ButtonStyle;
const FLinearColor NormalTint = bActive ? FLinearColor(0.16f, 0.46f, 0.39f, 0.92f) : FLinearColor(0.90f, 0.83f, 0.66f, 0.76f);
const FLinearColor HoverTint = bActive ? FLinearColor(0.19f, 0.54f, 0.46f, 0.95f) : FLinearColor(0.96f, 0.89f, 0.72f, 0.90f);
ButtonStyle.SetNormal(MakeAttributeMenuBrush(bActive ? AttributeJadeTexturePath : AttributePaperTexturePath, FVector2D(210.0f, 54.0f), NormalTint));
ButtonStyle.SetHovered(MakeAttributeMenuBrush(bActive ? AttributeJadeTexturePath : AttributePaperTexturePath, FVector2D(210.0f, 54.0f), HoverTint));
ButtonStyle.SetPressed(MakeAttributeMenuBrush(AttributeCinnabarTexturePath, FVector2D(210.0f, 54.0f), FLinearColor(0.72f, 0.24f, 0.14f, 0.92f)));
Button->SetStyle(ButtonStyle);
Button->SetBackgroundColor(FLinearColor::White);
}
UBorder* CreateAttributeMenuLine(UWidgetTree* WidgetTree, const FName WidgetName)
{
UBorder* Line = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), WidgetName);
Line->SetBrush(MakeAttributeMenuBrush(AttributeGoldRuleTexturePath, FVector2D(512.0f, 24.0f), FLinearColor(1.0f, 0.86f, 0.44f, 0.80f), ESlateBrushDrawType::Image, FMargin(0.0f)));
return Line;
}
TArray<FGameplayAttribute> MakeTrackedAttributes() TArray<FGameplayAttribute> MakeTrackedAttributes()
{ {
return { return {
@@ -180,7 +275,7 @@ void UPHYAttributeMenuWidget::BuildNativeWidgetTree()
WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient); WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient);
} }
if (WidgetTree->RootWidget && SummaryWidget && PageSwitcher && OverviewPage && CombatPage && ElementPage) if (WidgetTree->RootWidget && SummaryWidget && PageSwitcher && OverviewPage && CombatPage && ElementPage && HeaderHealthBar && HeaderManaBar && HeaderStaminaBar)
{ {
return; return;
} }
@@ -188,60 +283,107 @@ void UPHYAttributeMenuWidget::BuildNativeWidgetTree()
USafeZone* RootSafeZone = WidgetTree->ConstructWidget<USafeZone>(USafeZone::StaticClass(), TEXT("RootSafeZone")); USafeZone* RootSafeZone = WidgetTree->ConstructWidget<USafeZone>(USafeZone::StaticClass(), TEXT("RootSafeZone"));
WidgetTree->RootWidget = RootSafeZone; WidgetTree->RootWidget = RootSafeZone;
UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RootBorder")); UBorder* RootWash = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RootWash"));
RootBorder->SetBrushColor(FLinearColor(0.83f, 0.78f, 0.64f, 0.94f)); RootWash->SetBrushColor(FLinearColor(0.08f, 0.10f, 0.09f, 0.96f));
RootBorder->SetPadding(FMargin(28.0f)); RootSafeZone->SetContent(RootWash);
RootSafeZone->SetContent(RootBorder);
UHorizontalBox* MainBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("MainBox")); UScaleBox* DesignScaleBox = WidgetTree->ConstructWidget<UScaleBox>(UScaleBox::StaticClass(), TEXT("DesignScaleBox"));
RootBorder->SetContent(MainBox); DesignScaleBox->SetStretch(EStretch::ScaleToFit);
DesignScaleBox->SetStretchDirection(EStretchDirection::Both);
RootWash->SetContent(DesignScaleBox);
USizeBox* DesignSizeBox = WidgetTree->ConstructWidget<USizeBox>(USizeBox::StaticClass(), TEXT("DesignSizeBox"));
DesignSizeBox->SetWidthOverride(AttributeDesignWidth);
DesignSizeBox->SetHeightOverride(AttributeDesignHeight);
DesignScaleBox->AddChild(DesignSizeBox);
UCanvasPanel* DesignCanvas = WidgetTree->ConstructWidget<UCanvasPanel>(UCanvasPanel::StaticClass(), TEXT("DesignCanvas"));
DesignSizeBox->AddChild(DesignCanvas);
UBorder* BackgroundPanel = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("BackgroundPanel"));
BackgroundPanel->SetBrush(MakeAttributeMenuBrush(AttributePaperTexturePath, FVector2D(AttributeDesignWidth, AttributeDesignHeight), FLinearColor(0.96f, 0.93f, 0.84f, 1.0f), ESlateBrushDrawType::Box, FMargin(0.035f)));
AddAttributeMenuCanvasChild(DesignCanvas, BackgroundPanel, FVector2D(0.0f, 0.0f), FVector2D(AttributeDesignWidth, AttributeDesignHeight), 0);
UBorder* TitlePlaque = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("TitlePlaque"));
TitlePlaque->SetBrush(MakeAttributeMenuBrush(AttributeJadeTexturePath, FVector2D(390.0f, 88.0f), FLinearColor(0.18f, 0.34f, 0.30f, 0.98f)));
TitlePlaque->SetPadding(FMargin(78.0f, 0.0f, 0.0f, 4.0f));
AddAttributeMenuCanvasChild(DesignCanvas, TitlePlaque, FVector2D(0.0f, 7.0f), FVector2D(402.0f, 88.0f), 3);
UTextBlock* TitleText = CreateAttributeMenuText(WidgetTree, TEXT("TitleText"), FText::FromString(TEXT("角色属性")), 31, FLinearColor(0.99f, 0.88f, 0.61f, 1.0f));
TitlePlaque->SetContent(TitleText);
UButton* AttributeNavButton = CreateAttributeNavButton(WidgetTree, TEXT("AttributeNavButton"), FText::FromString(TEXT("属性")), true);
AddAttributeMenuCanvasChild(DesignCanvas, AttributeNavButton, FVector2D(552.0f, 9.0f), FVector2D(170.0f, 74.0f), 3);
UButton* EquipNavButton = CreateAttributeNavButton(WidgetTree, TEXT("EquipNavButton"), FText::FromString(TEXT("装备")), false);
AddAttributeMenuCanvasChild(DesignCanvas, EquipNavButton, FVector2D(764.0f, 11.0f), FVector2D(155.0f, 70.0f), 3);
UButton* SkillNavButton = CreateAttributeNavButton(WidgetTree, TEXT("SkillNavButton"), FText::FromString(TEXT("技能")), false);
AddAttributeMenuCanvasChild(DesignCanvas, SkillNavButton, FVector2D(978.0f, 11.0f), FVector2D(155.0f, 70.0f), 3);
UButton* BagNavButton = CreateAttributeNavButton(WidgetTree, TEXT("BagNavButton"), FText::FromString(TEXT("背包")), false);
AddAttributeMenuCanvasChild(DesignCanvas, BagNavButton, FVector2D(1188.0f, 11.0f), FVector2D(155.0f, 70.0f), 3);
UBorder* HeaderRule = CreateAttributeMenuLine(WidgetTree, TEXT("HeaderRule"));
AddAttributeMenuCanvasChild(DesignCanvas, HeaderRule, FVector2D(392.0f, 85.0f), FVector2D(1245.0f, 18.0f), 2);
SummaryWidget = WidgetTree->ConstructWidget<UPHYAttributeSummaryWidget>(UPHYAttributeSummaryWidget::StaticClass(), TEXT("SummaryWidget")); SummaryWidget = WidgetTree->ConstructWidget<UPHYAttributeSummaryWidget>(UPHYAttributeSummaryWidget::StaticClass(), TEXT("SummaryWidget"));
USizeBox* SummarySizeBox = WidgetTree->ConstructWidget<USizeBox>(USizeBox::StaticClass(), TEXT("SummarySizeBox")); UBorder* SummaryPanel = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("SummaryPanel"));
SummarySizeBox->SetWidthOverride(360.0f); SummaryPanel->SetBrush(MakeAttributeMenuBrush(AttributePaperTexturePath, FVector2D(462.0f, 710.0f), FLinearColor(0.98f, 0.96f, 0.88f, 0.96f), ESlateBrushDrawType::Box, FMargin(0.085f)));
SummarySizeBox->AddChild(SummaryWidget); SummaryPanel->SetPadding(FMargin(27.0f, 24.0f, 27.0f, 22.0f));
if (UHorizontalBoxSlot* SummarySlot = MainBox->AddChildToHorizontalBox(SummarySizeBox)) SummaryPanel->SetContent(SummaryWidget);
{ AddAttributeMenuCanvasChild(DesignCanvas, SummaryPanel, FVector2D(35.0f, 103.0f), FVector2D(462.0f, 710.0f), 2);
SummarySlot->SetSize(FSlateChildSize(ESlateSizeRule::Automatic));
SummarySlot->SetPadding(FMargin(0.0f, 0.0f, 18.0f, 0.0f));
}
UBorder* PageBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("PageBorder")); UBorder* PageBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("PageBorder"));
PageBorder->SetBrushColor(FLinearColor(0.96f, 0.92f, 0.82f, 0.72f)); PageBorder->SetBrush(MakeAttributeMenuBrush(AttributePaperTexturePath, FVector2D(1120.0f, 735.0f), FLinearColor(0.98f, 0.96f, 0.88f, 0.92f), ESlateBrushDrawType::Box, FMargin(0.055f)));
PageBorder->SetPadding(FMargin(22.0f)); PageBorder->SetPadding(FMargin(28.0f, 22.0f, 28.0f, 24.0f));
if (UHorizontalBoxSlot* PageSlot = MainBox->AddChildToHorizontalBox(PageBorder)) AddAttributeMenuCanvasChild(DesignCanvas, PageBorder, FVector2D(515.0f, 103.0f), FVector2D(1120.0f, 735.0f), 2);
{
PageSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
}
UVerticalBox* PageBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("PageBox")); UVerticalBox* PageBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("PageBox"));
PageBorder->SetContent(PageBox); PageBorder->SetContent(PageBox);
UTextBlock* HeaderText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("HeaderText")); UTextBlock* ResourceTitleText = CreateAttributeMenuText(WidgetTree, TEXT("ResourceTitleText"), FText::FromString(TEXT("战斗资源")), 22, FLinearColor(0.39f, 0.22f, 0.10f, 1.0f));
HeaderText->SetText(FText::FromString(TEXT("角色属性"))); PageBox->AddChildToVerticalBox(ResourceTitleText);
HeaderText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 28));
HeaderText->SetColorAndOpacity(FSlateColor(FLinearColor(0.35f, 0.13f, 0.06f, 1.0f))); UBorder* ResourceRule = CreateAttributeMenuLine(WidgetTree, TEXT("ResourceRule"));
PageBox->AddChildToVerticalBox(HeaderText); if (UVerticalBoxSlot* ResourceRuleSlot = PageBox->AddChildToVerticalBox(ResourceRule))
{
ResourceRuleSlot->SetPadding(FMargin(0.0f, 4.0f, 0.0f, 8.0f));
}
HeaderHealthBar = WidgetTree->ConstructWidget<UPHYAttributeResourceBarWidget>(UPHYAttributeResourceBarWidget::StaticClass(), TEXT("HeaderHealthBar"));
HeaderManaBar = WidgetTree->ConstructWidget<UPHYAttributeResourceBarWidget>(UPHYAttributeResourceBarWidget::StaticClass(), TEXT("HeaderManaBar"));
HeaderStaminaBar = WidgetTree->ConstructWidget<UPHYAttributeResourceBarWidget>(UPHYAttributeResourceBarWidget::StaticClass(), TEXT("HeaderStaminaBar"));
if (UVerticalBoxSlot* HealthSlot = PageBox->AddChildToVerticalBox(HeaderHealthBar))
{
HealthSlot->SetPadding(FMargin(4.0f, 0.0f, 0.0f, 2.0f));
}
if (UVerticalBoxSlot* ManaSlot = PageBox->AddChildToVerticalBox(HeaderManaBar))
{
ManaSlot->SetPadding(FMargin(4.0f, 0.0f, 0.0f, 2.0f));
}
if (UVerticalBoxSlot* StaminaSlot = PageBox->AddChildToVerticalBox(HeaderStaminaBar))
{
StaminaSlot->SetPadding(FMargin(4.0f, 0.0f, 0.0f, 12.0f));
}
UHorizontalBox* TabBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("TabBox")); UHorizontalBox* TabBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("TabBox"));
if (UVerticalBoxSlot* TabSlot = PageBox->AddChildToVerticalBox(TabBox)) if (UVerticalBoxSlot* TabSlot = PageBox->AddChildToVerticalBox(TabBox))
{ {
TabSlot->SetPadding(FMargin(0.0f, 12.0f, 0.0f, 16.0f)); TabSlot->SetPadding(FMargin(0.0f, 2.0f, 0.0f, 14.0f));
} }
OverviewTabButton = CreateTabButton(TEXT("OverviewTabButton"), FText::FromString(TEXT("总览"))); OverviewTabButton = CreateTabButton(TEXT("OverviewTabButton"), FText::FromString(TEXT("核心属性")));
CombatTabButton = CreateTabButton(TEXT("CombatTabButton"), FText::FromString(TEXT("战斗衍生"))); CombatTabButton = CreateTabButton(TEXT("CombatTabButton"), FText::FromString(TEXT("战斗衍生")));
ElementTabButton = CreateTabButton(TEXT("ElementTabButton"), FText::FromString(TEXT("元素衍生"))); ElementTabButton = CreateTabButton(TEXT("ElementTabButton"), FText::FromString(TEXT("元素衍生")));
TabBox->AddChildToHorizontalBox(OverviewTabButton); if (UHorizontalBoxSlot* OverviewTabSlot = TabBox->AddChildToHorizontalBox(OverviewTabButton))
{
OverviewTabSlot->SetPadding(FMargin(0.0f, 0.0f, 10.0f, 0.0f));
}
if (UHorizontalBoxSlot* CombatTabSlot = TabBox->AddChildToHorizontalBox(CombatTabButton)) if (UHorizontalBoxSlot* CombatTabSlot = TabBox->AddChildToHorizontalBox(CombatTabButton))
{ {
CombatTabSlot->SetPadding(FMargin(8.0f, 0.0f, 0.0f, 0.0f)); CombatTabSlot->SetPadding(FMargin(0.0f, 0.0f, 10.0f, 0.0f));
}
if (UHorizontalBoxSlot* ElementTabSlot = TabBox->AddChildToHorizontalBox(ElementTabButton))
{
ElementTabSlot->SetPadding(FMargin(8.0f, 0.0f, 0.0f, 0.0f));
} }
TabBox->AddChildToHorizontalBox(ElementTabButton);
PageSwitcher = WidgetTree->ConstructWidget<UWidgetSwitcher>(UWidgetSwitcher::StaticClass(), TEXT("PageSwitcher")); PageSwitcher = WidgetTree->ConstructWidget<UWidgetSwitcher>(UWidgetSwitcher::StaticClass(), TEXT("PageSwitcher"));
if (UVerticalBoxSlot* SwitcherSlot = PageBox->AddChildToVerticalBox(PageSwitcher)) if (UVerticalBoxSlot* SwitcherSlot = PageBox->AddChildToVerticalBox(PageSwitcher))
@@ -260,6 +402,13 @@ void UPHYAttributeMenuWidget::BuildNativeWidgetTree()
CombatTabButton->OnClicked.AddUniqueDynamic(this, &UPHYAttributeMenuWidget::HandleCombatTabClicked); CombatTabButton->OnClicked.AddUniqueDynamic(this, &UPHYAttributeMenuWidget::HandleCombatTabClicked);
ElementTabButton->OnClicked.AddUniqueDynamic(this, &UPHYAttributeMenuWidget::HandleElementTabClicked); ElementTabButton->OnClicked.AddUniqueDynamic(this, &UPHYAttributeMenuWidget::HandleElementTabClicked);
UButton* ConfirmButton = CreateAttributeNavButton(WidgetTree, TEXT("ConfirmButton"), FText::FromString(TEXT("确认")), true);
AddAttributeMenuCanvasChild(DesignCanvas, ConfirmButton, FVector2D(484.0f, 865.0f), FVector2D(255.0f, 58.0f), 3);
UButton* BackButton = CreateAttributeNavButton(WidgetTree, TEXT("BackButton"), FText::FromString(TEXT("返回")), false);
AddAttributeMenuCanvasChild(DesignCanvas, BackButton, FVector2D(774.0f, 865.0f), FVector2D(210.0f, 58.0f), 3);
UButton* ResetButton = CreateAttributeNavButton(WidgetTree, TEXT("ResetButton"), FText::FromString(TEXT("重置加点")), false);
AddAttributeMenuCanvasChild(DesignCanvas, ResetButton, FVector2D(1014.0f, 865.0f), FVector2D(260.0f, 58.0f), 3);
SetActivePage(ActivePageIndex); SetActivePage(ActivePageIndex);
RefreshAttributePages(); RefreshAttributePages();
} }
@@ -267,12 +416,12 @@ void UPHYAttributeMenuWidget::BuildNativeWidgetTree()
UButton* UPHYAttributeMenuWidget::CreateTabButton(const FName ButtonName, const FText Label) UButton* UPHYAttributeMenuWidget::CreateTabButton(const FName ButtonName, const FText Label)
{ {
UButton* TabButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), ButtonName); UButton* TabButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), ButtonName);
TabButton->SetBackgroundColor(FLinearColor(0.25f, 0.48f, 0.42f, 0.78f)); ApplyAttributeSubTabStyle(TabButton, false);
UTextBlock* TabText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass()); UTextBlock* TabText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass());
TabText->SetText(Label); TabText->SetText(Label);
TabText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 16)); TabText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 18));
TabText->SetColorAndOpacity(FSlateColor(FLinearColor(0.98f, 0.94f, 0.84f, 1.0f))); TabText->SetColorAndOpacity(FSlateColor(FLinearColor(0.30f, 0.23f, 0.15f, 1.0f)));
TabButton->SetContent(TabText); TabButton->SetContent(TabText);
return TabButton; return TabButton;
} }
@@ -289,21 +438,9 @@ void UPHYAttributeMenuWidget::SetActivePage(const int32 NewPageIndex)
void UPHYAttributeMenuWidget::UpdateTabVisuals() void UPHYAttributeMenuWidget::UpdateTabVisuals()
{ {
const FLinearColor ActiveColor(0.68f, 0.21f, 0.12f, 0.92f); ApplyAttributeSubTabStyle(OverviewTabButton, ActivePageIndex == 0);
const FLinearColor InactiveColor(0.25f, 0.48f, 0.42f, 0.78f); ApplyAttributeSubTabStyle(CombatTabButton, ActivePageIndex == 1);
ApplyAttributeSubTabStyle(ElementTabButton, ActivePageIndex == 2);
if (OverviewTabButton)
{
OverviewTabButton->SetBackgroundColor(ActivePageIndex == 0 ? ActiveColor : InactiveColor);
}
if (CombatTabButton)
{
CombatTabButton->SetBackgroundColor(ActivePageIndex == 1 ? ActiveColor : InactiveColor);
}
if (ElementTabButton)
{
ElementTabButton->SetBackgroundColor(ActivePageIndex == 2 ? ActiveColor : InactiveColor);
}
} }
void UPHYAttributeMenuWidget::BindToPlayerState(APHYPlayerState* NewPlayerState) void UPHYAttributeMenuWidget::BindToPlayerState(APHYPlayerState* NewPlayerState)
@@ -391,6 +528,25 @@ void UPHYAttributeMenuWidget::RefreshAttributePages()
GetAttributeValue(UPHYCombatAttributeSet::GetMaxStaminaAttribute())); GetAttributeValue(UPHYCombatAttributeSet::GetMaxStaminaAttribute()));
} }
const float Health = GetAttributeValue(UPHYCombatAttributeSet::GetHealthAttribute());
const float MaxHealth = GetAttributeValue(UPHYCombatAttributeSet::GetMaxHealthAttribute());
const float Mana = GetAttributeValue(UPHYCombatAttributeSet::GetManaAttribute());
const float MaxMana = GetAttributeValue(UPHYCombatAttributeSet::GetMaxManaAttribute());
const float Stamina = GetAttributeValue(UPHYCombatAttributeSet::GetStaminaAttribute());
const float MaxStamina = GetAttributeValue(UPHYCombatAttributeSet::GetMaxStaminaAttribute());
if (HeaderHealthBar)
{
HeaderHealthBar->SetResource(FText::FromString(TEXT("生命值 (HP)")), Health, MaxHealth, FLinearColor(0.78f, 0.18f, 0.14f, 1.0f));
}
if (HeaderManaBar)
{
HeaderManaBar->SetResource(FText::FromString(TEXT("法力值 (MP)")), Mana, MaxMana, FLinearColor(0.12f, 0.45f, 0.88f, 1.0f));
}
if (HeaderStaminaBar)
{
HeaderStaminaBar->SetResource(FText::FromString(TEXT("耐力值 (ST)")), Stamina, MaxStamina, FLinearColor(0.12f, 0.67f, 0.58f, 1.0f));
}
UAbilitySystemComponent* AbilitySystemComponent = BoundAbilitySystemComponent.Get(); UAbilitySystemComponent* AbilitySystemComponent = BoundAbilitySystemComponent.Get();
if (OverviewPage) if (OverviewPage)
{ {

View File

@@ -37,7 +37,7 @@ namespace
void UPHYAttributeOverviewPageWidget::RefreshAttributes(UAbilitySystemComponent* AbilitySystemComponent) void UPHYAttributeOverviewPageWidget::RefreshAttributes(UAbilitySystemComponent* AbilitySystemComponent)
{ {
SetPageTitle(FText::FromString(TEXT("属性总览"))); SetPageTitle(FText::FromString(TEXT("核心属性")));
ClearGroups(); ClearGroups();
UPHYAttributeGroupWidget* CoreGroup = AddGroup(FText::FromString(TEXT("核心属性"))); UPHYAttributeGroupWidget* CoreGroup = AddGroup(FText::FromString(TEXT("核心属性")));
@@ -47,9 +47,4 @@ void UPHYAttributeOverviewPageWidget::RefreshAttributes(UAbilitySystemComponent*
AddOverviewAttributeRow(CoreGroup, TEXT("智力"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetIntelligenceAttribute())), true); AddOverviewAttributeRow(CoreGroup, TEXT("智力"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetIntelligenceAttribute())), true);
AddOverviewAttributeRow(CoreGroup, TEXT("精神"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetSpiritAttribute())), true); AddOverviewAttributeRow(CoreGroup, TEXT("精神"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetSpiritAttribute())), true);
AddOverviewAttributeRow(CoreGroup, TEXT("感知"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetPerceptionAttribute())), true); AddOverviewAttributeRow(CoreGroup, TEXT("感知"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetPerceptionAttribute())), true);
UPHYAttributeGroupWidget* ResourceGroup = AddGroup(FText::FromString(TEXT("战斗资源")));
AddOverviewAttributeRow(ResourceGroup, TEXT("生命值"), MakeOverviewPairText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetHealthAttribute()), GetOverviewAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxHealthAttribute())));
AddOverviewAttributeRow(ResourceGroup, TEXT("法力值"), MakeOverviewPairText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetManaAttribute()), GetOverviewAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxManaAttribute())));
AddOverviewAttributeRow(ResourceGroup, TEXT("耐力值"), MakeOverviewPairText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetStaminaAttribute()), GetOverviewAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxStaminaAttribute())));
} }

View File

@@ -5,22 +5,42 @@
#include UE_INLINE_GENERATED_CPP_BY_NAME(PHYAttributeResourceBarWidget) #include UE_INLINE_GENERATED_CPP_BY_NAME(PHYAttributeResourceBarWidget)
#include "Blueprint/WidgetTree.h" #include "Blueprint/WidgetTree.h"
#include "Components/Border.h"
#include "Components/HorizontalBox.h" #include "Components/HorizontalBox.h"
#include "Components/HorizontalBoxSlot.h" #include "Components/HorizontalBoxSlot.h"
#include "Components/ProgressBar.h" #include "Components/ProgressBar.h"
#include "Components/SizeBox.h"
#include "Components/TextBlock.h" #include "Components/TextBlock.h"
#include "Components/VerticalBox.h" #include "Components/VerticalBox.h"
#include "Components/VerticalBoxSlot.h" #include "Components/VerticalBoxSlot.h"
#include "Engine/Texture2D.h"
#include "Fonts/SlateFontInfo.h" #include "Fonts/SlateFontInfo.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
#include "Styling/SlateBrush.h"
#include "Widgets/SWidget.h" #include "Widgets/SWidget.h"
namespace namespace
{ {
const TCHAR* const AttributeResourceRowTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_RowStrip.T_PHY_UI_RowStrip");
float MakePercent(const float CurrentValue, const float MaxValue) float MakePercent(const float CurrentValue, const float MaxValue)
{ {
return MaxValue > UE_SMALL_NUMBER ? FMath::Clamp(CurrentValue / MaxValue, 0.0f, 1.0f) : 0.0f; return MaxValue > UE_SMALL_NUMBER ? FMath::Clamp(CurrentValue / MaxValue, 0.0f, 1.0f) : 0.0f;
} }
FSlateBrush MakeAttributeResourceBrush()
{
FSlateBrush Brush;
Brush.DrawAs = ESlateBrushDrawType::Box;
Brush.Margin = FMargin(0.08f);
Brush.ImageSize = FVector2D(512.0f, 64.0f);
Brush.TintColor = FSlateColor(FLinearColor(1.0f, 1.0f, 1.0f, 0.88f));
if (UTexture2D* Texture = LoadObject<UTexture2D>(nullptr, AttributeResourceRowTexturePath))
{
Brush.SetResourceObject(Texture);
}
return Brush;
}
} }
UPHYAttributeResourceBarWidget::UPHYAttributeResourceBarWidget(const FObjectInitializer& ObjectInitializer) UPHYAttributeResourceBarWidget::UPHYAttributeResourceBarWidget(const FObjectInitializer& ObjectInitializer)
@@ -61,32 +81,43 @@ void UPHYAttributeResourceBarWidget::BuildNativeWidgetTree()
return; return;
} }
UVerticalBox* RootBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("RootBox")); UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RootBorder"));
WidgetTree->RootWidget = RootBox; RootBorder->SetBrush(MakeAttributeResourceBrush());
RootBorder->SetPadding(FMargin(10.0f, 5.0f));
WidgetTree->RootWidget = RootBorder;
UHorizontalBox* HeaderBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("HeaderBox")); UHorizontalBox* HeaderBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("HeaderBox"));
if (UVerticalBoxSlot* HeaderSlot = RootBox->AddChildToVerticalBox(HeaderBox)) RootBorder->SetContent(HeaderBox);
{
HeaderSlot->SetPadding(FMargin(0.0f, 2.0f, 0.0f, 2.0f));
}
LabelText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("LabelText")); LabelText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("LabelText"));
LabelText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 14)); LabelText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 16));
LabelText->SetColorAndOpacity(FSlateColor(FLinearColor(0.30f, 0.26f, 0.20f, 1.0f))); LabelText->SetColorAndOpacity(FSlateColor(FLinearColor(0.34f, 0.27f, 0.17f, 1.0f)));
if (UHorizontalBoxSlot* LabelSlot = HeaderBox->AddChildToHorizontalBox(LabelText)) if (UHorizontalBoxSlot* LabelSlot = HeaderBox->AddChildToHorizontalBox(LabelText))
{ {
LabelSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill)); LabelSlot->SetSize(FSlateChildSize(ESlateSizeRule::Automatic));
LabelSlot->SetPadding(FMargin(0.0f, 0.0f, 18.0f, 0.0f));
LabelSlot->SetVerticalAlignment(VAlign_Center);
} }
USizeBox* BarSizeBox = WidgetTree->ConstructWidget<USizeBox>(USizeBox::StaticClass(), TEXT("BarSizeBox"));
BarSizeBox->SetHeightOverride(13.0f);
if (UHorizontalBoxSlot* BarOuterSlot = HeaderBox->AddChildToHorizontalBox(BarSizeBox))
{
BarOuterSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
BarOuterSlot->SetPadding(FMargin(0.0f, 2.0f, 18.0f, 0.0f));
BarOuterSlot->SetVerticalAlignment(VAlign_Center);
}
ResourceBar = WidgetTree->ConstructWidget<UProgressBar>(UProgressBar::StaticClass(), TEXT("ResourceBar"));
BarSizeBox->AddChild(ResourceBar);
ValueText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("ValueText")); ValueText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("ValueText"));
ValueText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 14)); ValueText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 14));
ValueText->SetColorAndOpacity(FSlateColor(FLinearColor(0.10f, 0.26f, 0.23f, 1.0f))); ValueText->SetColorAndOpacity(FSlateColor(FLinearColor(0.23f, 0.20f, 0.16f, 1.0f)));
HeaderBox->AddChildToHorizontalBox(ValueText); if (UHorizontalBoxSlot* ValueSlot = HeaderBox->AddChildToHorizontalBox(ValueText))
ResourceBar = WidgetTree->ConstructWidget<UProgressBar>(UProgressBar::StaticClass(), TEXT("ResourceBar"));
if (UVerticalBoxSlot* BarSlot = RootBox->AddChildToVerticalBox(ResourceBar))
{ {
BarSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 7.0f)); ValueSlot->SetSize(FSlateChildSize(ESlateSizeRule::Automatic));
ValueSlot->SetVerticalAlignment(VAlign_Center);
} }
UpdateResourceWidgets(); UpdateResourceWidgets();

View File

@@ -5,14 +5,38 @@
#include UE_INLINE_GENERATED_CPP_BY_NAME(PHYAttributeRowWidget) #include UE_INLINE_GENERATED_CPP_BY_NAME(PHYAttributeRowWidget)
#include "Blueprint/WidgetTree.h" #include "Blueprint/WidgetTree.h"
#include "Components/Border.h"
#include "Components/Button.h" #include "Components/Button.h"
#include "Components/HorizontalBox.h" #include "Components/HorizontalBox.h"
#include "Components/HorizontalBoxSlot.h" #include "Components/HorizontalBoxSlot.h"
#include "Components/TextBlock.h" #include "Components/TextBlock.h"
#include "Engine/Texture2D.h"
#include "Fonts/SlateFontInfo.h" #include "Fonts/SlateFontInfo.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
#include "Styling/SlateBrush.h"
#include "Styling/SlateTypes.h"
#include "Widgets/SWidget.h" #include "Widgets/SWidget.h"
namespace
{
const TCHAR* const AttributeRowTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_RowStrip.T_PHY_UI_RowStrip");
const TCHAR* const AttributeRowCinnabarTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_CinnabarTab.T_PHY_UI_CinnabarTab");
FSlateBrush MakeAttributeRowBrush(const TCHAR* TexturePath, const FVector2D ImageSize, const FLinearColor Tint, const ESlateBrushDrawType::Type DrawAs = ESlateBrushDrawType::Box, const FMargin Margin = FMargin(0.08f))
{
FSlateBrush Brush;
Brush.DrawAs = DrawAs;
Brush.Margin = Margin;
Brush.ImageSize = ImageSize;
Brush.TintColor = FSlateColor(Tint);
if (UTexture2D* Texture = LoadObject<UTexture2D>(nullptr, TexturePath))
{
Brush.SetResourceObject(Texture);
}
return Brush;
}
}
UPHYAttributeRowWidget::UPHYAttributeRowWidget(const FObjectInitializer& ObjectInitializer) UPHYAttributeRowWidget::UPHYAttributeRowWidget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
{ {
@@ -45,39 +69,48 @@ void UPHYAttributeRowWidget::BuildNativeWidgetTree()
WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient); WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient);
} }
if (WidgetTree->RootWidget && RowBox && LabelText && ValueText && UpgradeButton && UpgradeText) if (WidgetTree->RootWidget && RowBorder && RowBox && LabelText && ValueText && UpgradeButton && UpgradeText)
{ {
return; return;
} }
RowBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RowBorder"));
RowBorder->SetBrush(MakeAttributeRowBrush(AttributeRowTexturePath, FVector2D(512.0f, 64.0f), FLinearColor(1.0f, 0.98f, 0.90f, 0.78f)));
RowBorder->SetPadding(FMargin(11.0f, 5.0f));
WidgetTree->RootWidget = RowBorder;
RowBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("RowBox")); RowBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("RowBox"));
WidgetTree->RootWidget = RowBox; RowBorder->SetContent(RowBox);
LabelText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("LabelText")); LabelText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("LabelText"));
LabelText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 15)); LabelText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 16));
LabelText->SetColorAndOpacity(FSlateColor(FLinearColor(0.28f, 0.25f, 0.20f, 1.0f))); LabelText->SetColorAndOpacity(FSlateColor(FLinearColor(0.31f, 0.25f, 0.16f, 1.0f)));
if (UHorizontalBoxSlot* LabelSlot = RowBox->AddChildToHorizontalBox(LabelText)) if (UHorizontalBoxSlot* LabelSlot = RowBox->AddChildToHorizontalBox(LabelText))
{ {
LabelSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill)); LabelSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
LabelSlot->SetPadding(FMargin(0.0f, 4.0f, 10.0f, 4.0f)); LabelSlot->SetPadding(FMargin(0.0f, 3.0f, 10.0f, 3.0f));
LabelSlot->SetVerticalAlignment(VAlign_Center); LabelSlot->SetVerticalAlignment(VAlign_Center);
} }
ValueText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("ValueText")); ValueText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("ValueText"));
ValueText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 15)); ValueText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 16));
ValueText->SetColorAndOpacity(FSlateColor(FLinearColor(0.08f, 0.24f, 0.22f, 1.0f))); ValueText->SetColorAndOpacity(FSlateColor(FLinearColor(0.08f, 0.36f, 0.28f, 1.0f)));
if (UHorizontalBoxSlot* ValueSlot = RowBox->AddChildToHorizontalBox(ValueText)) if (UHorizontalBoxSlot* ValueSlot = RowBox->AddChildToHorizontalBox(ValueText))
{ {
ValueSlot->SetSize(FSlateChildSize(ESlateSizeRule::Automatic)); ValueSlot->SetSize(FSlateChildSize(ESlateSizeRule::Automatic));
ValueSlot->SetPadding(FMargin(0.0f, 4.0f, 8.0f, 4.0f)); ValueSlot->SetPadding(FMargin(0.0f, 3.0f, 12.0f, 3.0f));
ValueSlot->SetVerticalAlignment(VAlign_Center); ValueSlot->SetVerticalAlignment(VAlign_Center);
} }
UpgradeButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("UpgradeButton")); UpgradeButton = WidgetTree->ConstructWidget<UButton>(UButton::StaticClass(), TEXT("UpgradeButton"));
UpgradeButton->SetBackgroundColor(FLinearColor(0.67f, 0.16f, 0.10f, 0.85f)); FButtonStyle UpgradeButtonStyle;
UpgradeButtonStyle.SetNormal(MakeAttributeRowBrush(AttributeRowCinnabarTexturePath, FVector2D(34.0f, 34.0f), FLinearColor(0.20f, 0.35f, 0.31f, 0.96f)));
UpgradeButtonStyle.SetHovered(MakeAttributeRowBrush(AttributeRowCinnabarTexturePath, FVector2D(34.0f, 34.0f), FLinearColor(0.27f, 0.48f, 0.42f, 1.0f)));
UpgradeButtonStyle.SetPressed(MakeAttributeRowBrush(AttributeRowCinnabarTexturePath, FVector2D(34.0f, 34.0f), FLinearColor(0.74f, 0.24f, 0.13f, 1.0f)));
UpgradeButton->SetStyle(UpgradeButtonStyle);
UpgradeText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("UpgradeText")); UpgradeText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("UpgradeText"));
UpgradeText->SetText(FText::FromString(TEXT("+"))); UpgradeText->SetText(FText::FromString(TEXT("+")));
UpgradeText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 14)); UpgradeText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 20));
UpgradeText->SetColorAndOpacity(FSlateColor(FLinearColor(0.98f, 0.92f, 0.78f, 1.0f))); UpgradeText->SetColorAndOpacity(FSlateColor(FLinearColor(0.98f, 0.92f, 0.78f, 1.0f)));
UpgradeButton->SetContent(UpgradeText); UpgradeButton->SetContent(UpgradeText);
if (UHorizontalBoxSlot* UpgradeSlot = RowBox->AddChildToHorizontalBox(UpgradeButton)) if (UHorizontalBoxSlot* UpgradeSlot = RowBox->AddChildToHorizontalBox(UpgradeButton))

View File

@@ -6,15 +6,40 @@
#include "Blueprint/WidgetTree.h" #include "Blueprint/WidgetTree.h"
#include "Components/Border.h" #include "Components/Border.h"
#include "Components/HorizontalBox.h"
#include "Components/HorizontalBoxSlot.h"
#include "Components/SizeBox.h"
#include "Components/Spacer.h" #include "Components/Spacer.h"
#include "Components/TextBlock.h" #include "Components/TextBlock.h"
#include "Components/VerticalBox.h" #include "Components/VerticalBox.h"
#include "Components/VerticalBoxSlot.h" #include "Components/VerticalBoxSlot.h"
#include "Engine/Texture2D.h"
#include "Fonts/SlateFontInfo.h" #include "Fonts/SlateFontInfo.h"
#include "Styling/CoreStyle.h" #include "Styling/CoreStyle.h"
#include "Styling/SlateBrush.h"
#include "UI/PHYAttributeResourceBarWidget.h" #include "UI/PHYAttributeResourceBarWidget.h"
#include "Widgets/SWidget.h" #include "Widgets/SWidget.h"
namespace
{
const TCHAR* const AttributeSummaryJadeTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_JadePanel.T_PHY_UI_JadePanel");
const TCHAR* const AttributeSummaryPortraitTexturePath = TEXT("/Game/AGame/UI/Attributes/Textures/T_PHY_UI_PortraitFrame.T_PHY_UI_PortraitFrame");
FSlateBrush MakeAttributeSummaryBrush(const TCHAR* TexturePath, const FVector2D ImageSize, const FLinearColor Tint, const ESlateBrushDrawType::Type DrawAs = ESlateBrushDrawType::Box, const FMargin Margin = FMargin(0.08f))
{
FSlateBrush Brush;
Brush.DrawAs = DrawAs;
Brush.Margin = Margin;
Brush.ImageSize = ImageSize;
Brush.TintColor = FSlateColor(Tint);
if (UTexture2D* Texture = LoadObject<UTexture2D>(nullptr, TexturePath))
{
Brush.SetResourceObject(Texture);
}
return Brush;
}
}
UPHYAttributeSummaryWidget::UPHYAttributeSummaryWidget(const FObjectInitializer& ObjectInitializer) UPHYAttributeSummaryWidget::UPHYAttributeSummaryWidget(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
{ {
@@ -60,50 +85,72 @@ void UPHYAttributeSummaryWidget::BuildNativeWidgetTree()
WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient); WidgetTree = NewObject<UWidgetTree>(this, TEXT("WidgetTree"), RF_Transient);
} }
if (WidgetTree->RootWidget && PlayerNameText && LevelText && CombatPowerText && ExperienceBar && HealthBar && ManaBar && StaminaBar) if (WidgetTree->RootWidget && PlayerNameText && LevelText && CombatPowerText && ExperienceBar && ResourceBox)
{ {
return; return;
} }
UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RootBorder")); UBorder* RootBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("RootBorder"));
RootBorder->SetBrushColor(FLinearColor(0.92f, 0.86f, 0.70f, 0.55f)); RootBorder->SetBrushColor(FLinearColor(1.0f, 1.0f, 1.0f, 0.0f));
RootBorder->SetPadding(FMargin(18.0f)); RootBorder->SetPadding(FMargin(0.0f));
WidgetTree->RootWidget = RootBorder; WidgetTree->RootWidget = RootBorder;
UVerticalBox* RootBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("RootBox")); UVerticalBox* RootBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("RootBox"));
RootBorder->SetContent(RootBox); RootBorder->SetContent(RootBox);
PlayerNameText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("PlayerNameText")); UHorizontalBox* HeaderBox = WidgetTree->ConstructWidget<UHorizontalBox>(UHorizontalBox::StaticClass(), TEXT("HeaderBox"));
PlayerNameText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 24)); if (UVerticalBoxSlot* HeaderSlot = RootBox->AddChildToVerticalBox(HeaderBox))
PlayerNameText->SetColorAndOpacity(FSlateColor(FLinearColor(0.28f, 0.16f, 0.08f, 1.0f))); {
RootBox->AddChildToVerticalBox(PlayerNameText); HeaderSlot->SetPadding(FMargin(0.0f, 0.0f, 0.0f, 14.0f));
}
UBorder* LevelSeal = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("LevelSeal"));
LevelSeal->SetBrush(MakeAttributeSummaryBrush(AttributeSummaryJadeTexturePath, FVector2D(92.0f, 92.0f), FLinearColor(0.18f, 0.33f, 0.30f, 0.96f)));
LevelSeal->SetPadding(FMargin(10.0f));
if (UHorizontalBoxSlot* SealSlot = HeaderBox->AddChildToHorizontalBox(LevelSeal))
{
SealSlot->SetSize(FSlateChildSize(ESlateSizeRule::Automatic));
SealSlot->SetPadding(FMargin(0.0f, 0.0f, 18.0f, 0.0f));
SealSlot->SetVerticalAlignment(VAlign_Center);
}
LevelText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("LevelText")); LevelText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("LevelText"));
LevelText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 17)); LevelText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 31));
LevelText->SetColorAndOpacity(FSlateColor(FLinearColor(0.14f, 0.34f, 0.30f, 1.0f))); LevelText->SetColorAndOpacity(FSlateColor(FLinearColor(1.0f, 0.86f, 0.55f, 1.0f)));
if (UVerticalBoxSlot* LevelSlot = RootBox->AddChildToVerticalBox(LevelText)) LevelSeal->SetContent(LevelText);
UVerticalBox* HeaderTextBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("HeaderTextBox"));
if (UHorizontalBoxSlot* HeaderTextSlot = HeaderBox->AddChildToHorizontalBox(HeaderTextBox))
{ {
LevelSlot->SetPadding(FMargin(0.0f, 8.0f, 0.0f, 0.0f)); HeaderTextSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill));
HeaderTextSlot->SetVerticalAlignment(VAlign_Center);
} }
PlayerNameText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("PlayerNameText"));
PlayerNameText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 24));
PlayerNameText->SetColorAndOpacity(FSlateColor(FLinearColor(0.26f, 0.20f, 0.12f, 1.0f)));
HeaderTextBox->AddChildToVerticalBox(PlayerNameText);
CombatPowerText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("CombatPowerText")); CombatPowerText = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("CombatPowerText"));
CombatPowerText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 17)); CombatPowerText->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 17));
CombatPowerText->SetColorAndOpacity(FSlateColor(FLinearColor(0.60f, 0.34f, 0.08f, 1.0f))); CombatPowerText->SetColorAndOpacity(FSlateColor(FLinearColor(0.60f, 0.36f, 0.11f, 1.0f)));
if (UVerticalBoxSlot* PowerSlot = RootBox->AddChildToVerticalBox(CombatPowerText)) if (UVerticalBoxSlot* PowerSlot = HeaderTextBox->AddChildToVerticalBox(CombatPowerText))
{ {
PowerSlot->SetPadding(FMargin(0.0f, 4.0f, 0.0f, 14.0f)); PowerSlot->SetPadding(FMargin(0.0f, 8.0f, 0.0f, 0.0f));
} }
UTextBlock* PortraitPlaceholder = WidgetTree->ConstructWidget<UTextBlock>(UTextBlock::StaticClass(), TEXT("PortraitPlaceholder")); USizeBox* PortraitSizeBox = WidgetTree->ConstructWidget<USizeBox>(USizeBox::StaticClass(), TEXT("PortraitSizeBox"));
PortraitPlaceholder->SetText(FText::FromString(TEXT("云纹角色剪影"))); PortraitSizeBox->SetHeightOverride(438.0f);
PortraitPlaceholder->SetFont(FSlateFontInfo(FCoreStyle::GetDefaultFont(), 20)); if (UVerticalBoxSlot* PortraitSlot = RootBox->AddChildToVerticalBox(PortraitSizeBox))
PortraitPlaceholder->SetColorAndOpacity(FSlateColor(FLinearColor(0.38f, 0.45f, 0.38f, 0.85f)));
if (UVerticalBoxSlot* PortraitSlot = RootBox->AddChildToVerticalBox(PortraitPlaceholder))
{ {
PortraitSlot->SetPadding(FMargin(0.0f, 22.0f, 0.0f, 24.0f)); PortraitSlot->SetPadding(FMargin(0.0f, 2.0f, 0.0f, 18.0f));
PortraitSlot->SetHorizontalAlignment(HAlign_Center);
} }
UBorder* PortraitBorder = WidgetTree->ConstructWidget<UBorder>(UBorder::StaticClass(), TEXT("PortraitBorder"));
PortraitBorder->SetBrush(MakeAttributeSummaryBrush(AttributeSummaryPortraitTexturePath, FVector2D(380.0f, 438.0f), FLinearColor(0.97f, 0.98f, 0.94f, 0.96f), ESlateBrushDrawType::Box, FMargin(0.075f)));
PortraitBorder->SetPadding(FMargin(10.0f));
PortraitSizeBox->AddChild(PortraitBorder);
ResourceBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("ResourceBox")); ResourceBox = WidgetTree->ConstructWidget<UVerticalBox>(UVerticalBox::StaticClass(), TEXT("ResourceBox"));
RootBox->AddChildToVerticalBox(ResourceBox); RootBox->AddChildToVerticalBox(ResourceBox);
@@ -113,9 +160,6 @@ void UPHYAttributeSummaryWidget::BuildNativeWidgetTree()
StaminaBar = WidgetTree->ConstructWidget<UPHYAttributeResourceBarWidget>(UPHYAttributeResourceBarWidget::StaticClass(), TEXT("StaminaBar")); StaminaBar = WidgetTree->ConstructWidget<UPHYAttributeResourceBarWidget>(UPHYAttributeResourceBarWidget::StaticClass(), TEXT("StaminaBar"));
ResourceBox->AddChildToVerticalBox(ExperienceBar); ResourceBox->AddChildToVerticalBox(ExperienceBar);
ResourceBox->AddChildToVerticalBox(HealthBar);
ResourceBox->AddChildToVerticalBox(ManaBar);
ResourceBox->AddChildToVerticalBox(StaminaBar);
UpdateSummaryWidgets(); UpdateSummaryWidgets();
} }
@@ -128,11 +172,11 @@ void UPHYAttributeSummaryWidget::UpdateSummaryWidgets()
} }
if (LevelText) if (LevelText)
{ {
LevelText->SetText(FText::FromString(FString::Printf(TEXT("等级 %d"), Level))); LevelText->SetText(FText::FromString(FString::Printf(TEXT("%d"), Level)));
} }
if (CombatPowerText) if (CombatPowerText)
{ {
CombatPowerText->SetText(FText::FromString(FString::Printf(TEXT("%d"), CombatPower))); CombatPowerText->SetText(FText::FromString(FString::Printf(TEXT("斗评分\n%d"), CombatPower)));
} }
if (ExperienceBar) if (ExperienceBar)
{ {

View File

@@ -12,6 +12,7 @@ class APlayerController;
class APHYPlayerState; class APHYPlayerState;
class UAbilitySystemComponent; class UAbilitySystemComponent;
class UButton; class UButton;
class UPHYAttributeResourceBarWidget;
class UHorizontalBox; class UHorizontalBox;
class UPHYAttributeOverviewPageWidget; class UPHYAttributeOverviewPageWidget;
class UPHYCombatDerivedAttributePageWidget; class UPHYCombatDerivedAttributePageWidget;
@@ -138,6 +139,18 @@ protected:
UPROPERTY(Transient) UPROPERTY(Transient)
TObjectPtr<UWidgetSwitcher> PageSwitcher; TObjectPtr<UWidgetSwitcher> PageSwitcher;
/** @brief 设计稿右侧顶部生命资源条。 */
UPROPERTY(Transient)
TObjectPtr<UPHYAttributeResourceBarWidget> HeaderHealthBar;
/** @brief 设计稿右侧顶部法力资源条。 */
UPROPERTY(Transient)
TObjectPtr<UPHYAttributeResourceBarWidget> HeaderManaBar;
/** @brief 设计稿右侧顶部耐力资源条。 */
UPROPERTY(Transient)
TObjectPtr<UPHYAttributeResourceBarWidget> HeaderStaminaBar;
/** @brief 总览分页。 */ /** @brief 总览分页。 */
UPROPERTY(Transient) UPROPERTY(Transient)
TObjectPtr<UPHYAttributeOverviewPageWidget> OverviewPage; TObjectPtr<UPHYAttributeOverviewPageWidget> OverviewPage;

View File

@@ -7,6 +7,7 @@
#include "PHYAttributeRowWidget.generated.h" #include "PHYAttributeRowWidget.generated.h"
class UButton; class UButton;
class UBorder;
class UHorizontalBox; class UHorizontalBox;
class UTextBlock; class UTextBlock;
@@ -55,6 +56,10 @@ protected:
/** @brief 行根容器。 */ /** @brief 行根容器。 */
UPROPERTY(Transient) UPROPERTY(Transient)
TObjectPtr<UBorder> RowBorder;
/** @brief 行水平容器。 */
UPROPERTY(Transient)
TObjectPtr<UHorizontalBox> RowBox; TObjectPtr<UHorizontalBox> RowBox;
/** @brief 属性名称文本。 */ /** @brief 属性名称文本。 */