Add attribute menu input processor

This commit is contained in:
2026-04-26 21:02:35 +08:00
parent 57363d9e7f
commit baeb4098c9
11 changed files with 227 additions and 58 deletions

View File

@@ -4,3 +4,4 @@ bRouteInputThroughGenericInputSystem=True
bBlockGameplayInputWhenUIFocused=True
DefaultMoveInputProcessorClass="/Script/PHY.PHYInputProcessor_Move"
DefaultLookInputProcessorClass="/Script/PHY.PHYInputProcessor_Look"
DefaultAttributeMenuInputProcessorClass="/Script/PHY.PHYInputProcessor_OpenAttributeMenu"

View File

@@ -15,4 +15,5 @@ namespace PHYGameplayTags
UE_DEFINE_GAMEPLAY_TAG(Input_Aim, "Input.Aim");
UE_DEFINE_GAMEPLAY_TAG(Input_LockOn, "Input.LockOn");
UE_DEFINE_GAMEPLAY_TAG(Input_Inventory_Toggle, "Input.Inventory.Toggle");
UE_DEFINE_GAMEPLAY_TAG(Input_Menu_Attribute, "Input.Menu.Attribute");
}

View File

@@ -0,0 +1,55 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Input/PHYInputProcessor_OpenAttributeMenu.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(PHYInputProcessor_OpenAttributeMenu)
#include "Characters/PHYPlayerCharacter.h"
#include "GIPS_InputSystemComponent.h"
#include "PHYGameplayTags.h"
#include "Player/PHYPlayerController.h"
UPHYInputProcessor_OpenAttributeMenu::UPHYInputProcessor_OpenAttributeMenu()
{
InputTags.AddTag(PHYGameplayTags::Input_Menu_Attribute);
TriggerEvents = {
ETriggerEvent::Started
};
}
bool UPHYInputProcessor_OpenAttributeMenu::CheckCanHandleInput_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag, const ETriggerEvent TriggerEvent) const
{
(void)ActionData;
if (!IC || InputTag != PHYGameplayTags::Input_Menu_Attribute || TriggerEvent != ETriggerEvent::Started)
{
return false;
}
const APHYPlayerCharacter* PlayerCharacter = Cast<APHYPlayerCharacter>(IC->GetControlledPawn());
const APHYPlayerController* PlayerController = PlayerCharacter ? PlayerCharacter->GetController<APHYPlayerController>() : nullptr;
return PlayerController && PlayerController->IsLocalController();
}
void UPHYInputProcessor_OpenAttributeMenu::HandleInputStarted_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const FGameplayTag InputTag) const
{
(void)InputTag;
RouteOpenAttributeMenuInput(IC, ActionData, ETriggerEvent::Started);
}
FString UPHYInputProcessor_OpenAttributeMenu::GetEditorFriendlyName_Implementation() const
{
return TEXT("PHY Open Attribute Menu");
}
bool UPHYInputProcessor_OpenAttributeMenu::RouteOpenAttributeMenuInput(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent) const
{
if (!IC)
{
return false;
}
APHYPlayerCharacter* PlayerCharacter = Cast<APHYPlayerCharacter>(IC->GetControlledPawn());
APHYPlayerController* PlayerController = PlayerCharacter ? PlayerCharacter->GetController<APHYPlayerController>() : nullptr;
return PlayerController ? PlayerController->RouteOpenAttributeMenuInputFromProcessor(ActionData, TriggerEvent) : false;
}

View File

@@ -7,6 +7,7 @@
#include "Characters/PHYPlayerCharacter.h"
#include "Characters/PHYCharacterSettings.h"
#include "Components/SLSCharacterMovementComponent.h"
#include "Game/PHYHUD.h"
#include "GIPS_InputSystemComponent.h"
#include "InputActionValue.h"
#include "PHYGameplayTags.h"
@@ -115,6 +116,15 @@ void APHYPlayerController::OnReceivedInput(const FInputActionInstance& ActionDat
return;
}
if (InputTag == PHYGameplayTags::Input_Menu_Attribute)
{
if (!ConsumeAttributeMenuProcessorGuard(TriggerEvent))
{
RouteOpenAttributeMenuInput(ActionData, TriggerEvent);
}
return;
}
if (APHYPlayerCharacter* PHYCharacter = GetPHYPlayerCharacter())
{
PHYCharacter->HandleInputTag(InputTag, TriggerEvent);
@@ -145,6 +155,18 @@ bool APHYPlayerController::RouteLookInputFromProcessor(const FInputActionInstanc
return RouteLookInput(ActionData, TriggerEvent);
}
bool APHYPlayerController::RouteOpenAttributeMenuInput(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
{
return HandleOpenAttributeMenuInput(ActionData, TriggerEvent);
}
bool APHYPlayerController::RouteOpenAttributeMenuInputFromProcessor(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
{
bAttributeMenuInputHandledByProcessor = true;
LastAttributeMenuInputProcessorTriggerEvent = TriggerEvent;
return RouteOpenAttributeMenuInput(ActionData, TriggerEvent);
}
bool APHYPlayerController::HandleMoveInput(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
{
APHYPlayerCharacter* PHYCharacter = GetPHYPlayerCharacter();
@@ -199,6 +221,33 @@ bool APHYPlayerController::ConsumeLookProcessorGuard(const ETriggerEvent Trigger
return false;
}
bool APHYPlayerController::ConsumeAttributeMenuProcessorGuard(const ETriggerEvent TriggerEvent)
{
if (bAttributeMenuInputHandledByProcessor && LastAttributeMenuInputProcessorTriggerEvent == TriggerEvent)
{
bAttributeMenuInputHandledByProcessor = false;
LastAttributeMenuInputProcessorTriggerEvent = ETriggerEvent::None;
return true;
}
bAttributeMenuInputHandledByProcessor = false;
LastAttributeMenuInputProcessorTriggerEvent = ETriggerEvent::None;
return false;
}
bool APHYPlayerController::HandleOpenAttributeMenuInput(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
{
(void)ActionData;
if (TriggerEvent != ETriggerEvent::Started || !IsLocalController())
{
return false;
}
APHYHUD* PHYHUD = GetHUD<APHYHUD>();
return PHYHUD && PHYHUD->OpenAttributeMenu(this);
}
bool APHYPlayerController::HandleLookInput(const FInputActionInstance& ActionData, const ETriggerEvent TriggerEvent)
{
CachedLookInput = IsInputReleased(TriggerEvent) ? FVector2D::ZeroVector : ExtractAxis2D(ActionData.GetValue());

View File

@@ -11,22 +11,22 @@
namespace
{
float GetAttributeValue(const UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAttribute& Attribute)
float GetOverviewAttributeValue(const UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAttribute& Attribute)
{
return AbilitySystemComponent ? AbilitySystemComponent->GetNumericAttribute(Attribute) : 0.0f;
}
FText MakeNumberText(const float Value)
FText MakeOverviewNumberText(const float Value)
{
return FText::FromString(FString::Printf(TEXT("%.0f"), Value));
}
FText MakePairText(const float CurrentValue, const float MaxValue)
FText MakeOverviewPairText(const float CurrentValue, const float MaxValue)
{
return FText::FromString(FString::Printf(TEXT("%.0f / %.0f"), FMath::Max(0.0f, CurrentValue), FMath::Max(0.0f, MaxValue)));
}
void AddAttributeRow(UPHYAttributeGroupWidget* GroupWidget, const TCHAR* Label, const FText& Value, const bool bCanUpgrade = false)
void AddOverviewAttributeRow(UPHYAttributeGroupWidget* GroupWidget, const TCHAR* Label, const FText& Value, const bool bCanUpgrade = false)
{
if (GroupWidget)
{
@@ -41,15 +41,15 @@ void UPHYAttributeOverviewPageWidget::RefreshAttributes(UAbilitySystemComponent*
ClearGroups();
UPHYAttributeGroupWidget* CoreGroup = AddGroup(FText::FromString(TEXT("核心属性")));
AddAttributeRow(CoreGroup, TEXT("力量"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetStrengthAttribute())), true);
AddAttributeRow(CoreGroup, TEXT("敏捷"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetDexterityAttribute())), true);
AddAttributeRow(CoreGroup, TEXT("体质"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetVitalityAttribute())), true);
AddAttributeRow(CoreGroup, TEXT("智力"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetIntelligenceAttribute())), true);
AddAttributeRow(CoreGroup, TEXT("精神"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetSpiritAttribute())), true);
AddAttributeRow(CoreGroup, TEXT("感知"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetPerceptionAttribute())), true);
AddOverviewAttributeRow(CoreGroup, TEXT("力量"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetStrengthAttribute())), true);
AddOverviewAttributeRow(CoreGroup, TEXT("敏捷"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetDexterityAttribute())), true);
AddOverviewAttributeRow(CoreGroup, TEXT("体质"), MakeOverviewNumberText(GetOverviewAttributeValue(AbilitySystemComponent, UPHYCoreAttributeSet::GetVitalityAttribute())), 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::GetPerceptionAttribute())), true);
UPHYAttributeGroupWidget* ResourceGroup = AddGroup(FText::FromString(TEXT("战斗资源")));
AddAttributeRow(ResourceGroup, TEXT("生命值"), MakePairText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetHealthAttribute()), GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxHealthAttribute())));
AddAttributeRow(ResourceGroup, TEXT("法力值"), MakePairText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetManaAttribute()), GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxManaAttribute())));
AddAttributeRow(ResourceGroup, TEXT("耐力值"), MakePairText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetStaminaAttribute()), GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxStaminaAttribute())));
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

@@ -10,27 +10,27 @@
namespace
{
float GetAttributeValue(const UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAttribute& Attribute)
float GetCombatDerivedAttributeValue(const UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAttribute& Attribute)
{
return AbilitySystemComponent ? AbilitySystemComponent->GetNumericAttribute(Attribute) : 0.0f;
}
FText MakeNumberText(const float Value)
FText MakeCombatNumberText(const float Value)
{
return FText::FromString(FString::Printf(TEXT("%.0f"), Value));
}
FText MakePercentText(const float Value)
FText MakeCombatPercentText(const float Value)
{
return FText::FromString(FString::Printf(TEXT("%.1f%%"), Value * 100.0f));
}
FText MakeMultiplierText(const float Value)
FText MakeCombatMultiplierText(const float Value)
{
return FText::FromString(FString::Printf(TEXT("x%.2f"), Value));
}
void AddAttributeRow(UPHYAttributeGroupWidget* GroupWidget, const TCHAR* Label, const FText& Value)
void AddCombatAttributeRow(UPHYAttributeGroupWidget* GroupWidget, const TCHAR* Label, const FText& Value)
{
if (GroupWidget)
{
@@ -45,28 +45,28 @@ void UPHYCombatDerivedAttributePageWidget::RefreshAttributes(UAbilitySystemCompo
ClearGroups();
UPHYAttributeGroupWidget* ResourceGroup = AddGroup(FText::FromString(TEXT("资源上限")));
AddAttributeRow(ResourceGroup, TEXT("当前生命"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetHealthAttribute())));
AddAttributeRow(ResourceGroup, TEXT("生命上限"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxHealthAttribute())));
AddAttributeRow(ResourceGroup, TEXT("当前法力"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetManaAttribute())));
AddAttributeRow(ResourceGroup, TEXT("法力上限"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxManaAttribute())));
AddAttributeRow(ResourceGroup, TEXT("当前耐力"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetStaminaAttribute())));
AddAttributeRow(ResourceGroup, TEXT("耐力上限"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxStaminaAttribute())));
AddCombatAttributeRow(ResourceGroup, TEXT("当前生命"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetHealthAttribute())));
AddCombatAttributeRow(ResourceGroup, TEXT("生命上限"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxHealthAttribute())));
AddCombatAttributeRow(ResourceGroup, TEXT("当前法力"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetManaAttribute())));
AddCombatAttributeRow(ResourceGroup, TEXT("法力上限"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxManaAttribute())));
AddCombatAttributeRow(ResourceGroup, TEXT("当前耐力"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetStaminaAttribute())));
AddCombatAttributeRow(ResourceGroup, TEXT("耐力上限"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMaxStaminaAttribute())));
UPHYAttributeGroupWidget* AttackGroup = AddGroup(FText::FromString(TEXT("攻击能力")));
AddAttributeRow(AttackGroup, TEXT("物理攻击"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetPhysicalAttackPowerAttribute())));
AddAttributeRow(AttackGroup, TEXT("法术强度"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetSpellPowerAttribute())));
AddAttributeRow(AttackGroup, TEXT("命中率"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetAccuracyAttribute())));
AddAttributeRow(AttackGroup, TEXT("暴击率"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetCriticalChanceAttribute())));
AddAttributeRow(AttackGroup, TEXT("暴击伤害"), MakeMultiplierText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetCriticalDamageAttribute())));
AddAttributeRow(AttackGroup, TEXT("攻击速度"), MakeMultiplierText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetAttackSpeedAttribute())));
AddAttributeRow(AttackGroup, TEXT("冷却缩减"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetCooldownReductionAttribute())));
AddAttributeRow(AttackGroup, TEXT("破防强度"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetGuardBreakPowerAttribute())));
AddAttributeRow(AttackGroup, TEXT("韧性伤害"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetPoiseDamageAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("物理攻击"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetPhysicalAttackPowerAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("法术强度"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetSpellPowerAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("命中率"), MakeCombatPercentText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetAccuracyAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("暴击率"), MakeCombatPercentText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetCriticalChanceAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("暴击伤害"), MakeCombatMultiplierText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetCriticalDamageAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("攻击速度"), MakeCombatMultiplierText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetAttackSpeedAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("冷却缩减"), MakeCombatPercentText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetCooldownReductionAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("破防强度"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetGuardBreakPowerAttribute())));
AddCombatAttributeRow(AttackGroup, TEXT("韧性伤害"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetPoiseDamageAttribute())));
UPHYAttributeGroupWidget* DefenseGroup = AddGroup(FText::FromString(TEXT("防御能力")));
AddAttributeRow(DefenseGroup, TEXT("护甲"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetArmorAttribute())));
AddAttributeRow(DefenseGroup, TEXT("魔法抗性"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMagicResistanceAttribute())));
AddAttributeRow(DefenseGroup, TEXT("闪避率"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetEvasionAttribute())));
AddAttributeRow(DefenseGroup, TEXT("格挡强度"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetBlockPowerAttribute())));
AddAttributeRow(DefenseGroup, TEXT("韧性"), MakeNumberText(GetAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetPoiseAttribute())));
AddCombatAttributeRow(DefenseGroup, TEXT("护甲"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetArmorAttribute())));
AddCombatAttributeRow(DefenseGroup, TEXT("魔法抗性"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetMagicResistanceAttribute())));
AddCombatAttributeRow(DefenseGroup, TEXT("闪避率"), MakeCombatPercentText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetEvasionAttribute())));
AddCombatAttributeRow(DefenseGroup, TEXT("格挡强度"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetBlockPowerAttribute())));
AddCombatAttributeRow(DefenseGroup, TEXT("韧性"), MakeCombatNumberText(GetCombatDerivedAttributeValue(AbilitySystemComponent, UPHYCombatAttributeSet::GetPoiseAttribute())));
}

View File

@@ -10,17 +10,17 @@
namespace
{
float GetAttributeValue(const UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAttribute& Attribute)
float GetElementDerivedAttributeValue(const UAbilitySystemComponent* AbilitySystemComponent, const FGameplayAttribute& Attribute)
{
return AbilitySystemComponent ? AbilitySystemComponent->GetNumericAttribute(Attribute) : 0.0f;
}
FText MakePercentText(const float Value)
FText MakeElementPercentText(const float Value)
{
return FText::FromString(FString::Printf(TEXT("%.1f%%"), Value * 100.0f));
}
void AddAttributeRow(UPHYAttributeGroupWidget* GroupWidget, const TCHAR* Label, const FText& Value)
void AddElementAttributeRow(UPHYAttributeGroupWidget* GroupWidget, const TCHAR* Label, const FText& Value)
{
if (GroupWidget)
{
@@ -35,23 +35,23 @@ void UPHYElementDerivedAttributePageWidget::RefreshAttributes(UAbilitySystemComp
ClearGroups();
UPHYAttributeGroupWidget* BonusGroup = AddGroup(FText::FromString(TEXT("元素伤害加成")));
AddAttributeRow(BonusGroup, TEXT("火伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetFireDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("水伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWaterDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("冰伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetIceDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("雷伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightningDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("地伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetEarthDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("风伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWindDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("光伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("暗伤加成"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetDarkDamageBonusAttribute())));
AddAttributeRow(BonusGroup, TEXT("元素穿透"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetElementPenetrationAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("火伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetFireDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("水伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWaterDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("冰伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetIceDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("雷伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightningDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("地伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetEarthDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("风伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWindDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("光伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("暗伤加成"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetDarkDamageBonusAttribute())));
AddElementAttributeRow(BonusGroup, TEXT("元素穿透"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetElementPenetrationAttribute())));
UPHYAttributeGroupWidget* ResistanceGroup = AddGroup(FText::FromString(TEXT("元素抗性")));
AddAttributeRow(ResistanceGroup, TEXT("火抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetFireResistanceAttribute())));
AddAttributeRow(ResistanceGroup, TEXT("水抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWaterResistanceAttribute())));
AddAttributeRow(ResistanceGroup, TEXT("冰抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetIceResistanceAttribute())));
AddAttributeRow(ResistanceGroup, TEXT("雷抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightningResistanceAttribute())));
AddAttributeRow(ResistanceGroup, TEXT("地抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetEarthResistanceAttribute())));
AddAttributeRow(ResistanceGroup, TEXT("风抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWindResistanceAttribute())));
AddAttributeRow(ResistanceGroup, TEXT("光抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightResistanceAttribute())));
AddAttributeRow(ResistanceGroup, TEXT("暗抗"), MakePercentText(GetAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetDarkResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("火抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetFireResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("水抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWaterResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("冰抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetIceResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("雷抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightningResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("地抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetEarthResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("风抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetWindResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("光抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetLightResistanceAttribute())));
AddElementAttributeRow(ResistanceGroup, TEXT("暗抗"), MakeElementPercentText(GetElementDerivedAttributeValue(AbilitySystemComponent, UPHYElementAttributeSet::GetDarkResistanceAttribute())));
}

View File

@@ -38,4 +38,7 @@ namespace PHYGameplayTags
/** @brief 背包开关输入。 */
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Input_Inventory_Toggle);
/** @brief 角色属性菜单开关输入。 */
UE_DECLARE_GAMEPLAY_TAG_EXTERN(Input_Menu_Attribute);
}

View File

@@ -0,0 +1,36 @@
// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "GIPS_InputProcessor.h"
#include "PHYInputProcessor_OpenAttributeMenu.generated.h"
/**
* @brief PHY 角色属性菜单输入处理器。
*
* 该处理器处理 `Input.Menu.Attribute`,并把本地输入路由到玩家控制器打开 Generic UI Menu 层。
*/
UCLASS(BlueprintType, Blueprintable, EditInlineNew, DefaultToInstanced)
class PHY_API UPHYInputProcessor_OpenAttributeMenu : public UGIPS_InputProcessor
{
GENERATED_BODY()
public:
/** @brief 构造默认响应的输入 Tag 和触发事件。 */
UPHYInputProcessor_OpenAttributeMenu();
protected:
/** @brief 检查当前输入组件是否能处理角色属性菜单输入。 */
virtual bool CheckCanHandleInput_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag, ETriggerEvent TriggerEvent) const override;
/** @brief 处理 Started 菜单输入。 */
virtual void HandleInputStarted_Implementation(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, FGameplayTag InputTag) const override;
/** @brief 返回编辑器里显示的处理器名称。 */
virtual FString GetEditorFriendlyName_Implementation() const override;
private:
/** @brief 将菜单输入发送给玩家控制器。 */
bool RouteOpenAttributeMenuInput(UGIPS_InputSystemComponent* IC, const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent) const;
};

View File

@@ -66,6 +66,10 @@ public:
/** @brief 默认视角输入处理器类,用于创建 GenericInputSystem 控制配置。 */
UPROPERTY(Config)
TSoftClassPtr<UGIPS_InputProcessor> DefaultLookInputProcessorClass;
/** @brief 默认角色属性菜单输入处理器类,用于推入 UI Menu 层。 */
UPROPERTY(Config)
TSoftClassPtr<UGIPS_InputProcessor> DefaultAttributeMenuInputProcessorClass;
};
/**

View File

@@ -59,6 +59,12 @@ public:
/** @brief 从 GenericInputSystem 处理器路由视角输入,并阻止同一事件被 fallback 重复执行。 */
bool RouteLookInputFromProcessor(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
/** @brief 路由角色属性菜单输入。 */
bool RouteOpenAttributeMenuInput(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
/** @brief 从 GenericInputSystem 处理器路由角色属性菜单输入,并阻止同一事件被 fallback 重复执行。 */
bool RouteOpenAttributeMenuInputFromProcessor(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
protected:
/** @brief 绑定玩家角色身上的 GenericInputSystem 输入委托。 */
virtual void BindInputEvents();
@@ -73,12 +79,18 @@ protected:
/** @brief 处理视角输入。 */
virtual bool HandleLookInput(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
/** @brief 处理角色属性菜单输入,本地推入 Generic UI Menu 层。 */
virtual bool HandleOpenAttributeMenuInput(const FInputActionInstance& ActionData, ETriggerEvent TriggerEvent);
/** @brief 查询并消费移动处理器留下的重复执行保护。 */
virtual bool ConsumeMoveProcessorGuard(ETriggerEvent TriggerEvent);
/** @brief 查询并消费视角处理器留下的重复执行保护。 */
virtual bool ConsumeLookProcessorGuard(ETriggerEvent TriggerEvent);
/** @brief 查询并消费属性菜单处理器留下的重复执行保护。 */
virtual bool ConsumeAttributeMenuProcessorGuard(ETriggerEvent TriggerEvent);
/** @brief 当前已经绑定输入委托的角色输入组件。 */
UPROPERTY(Transient)
TObjectPtr<UGIPS_InputSystemComponent> BoundInputSystemComponent;
@@ -110,4 +122,12 @@ protected:
/** @brief 最近一次由输入处理器处理的 Look 触发事件。 */
UPROPERTY(Transient)
ETriggerEvent LastLookInputProcessorTriggerEvent = ETriggerEvent::None;
/** @brief 输入处理器是否已经处理了最近一次属性菜单输入。 */
UPROPERTY(Transient)
bool bAttributeMenuInputHandledByProcessor = false;
/** @brief 最近一次由输入处理器处理的属性菜单触发事件。 */
UPROPERTY(Transient)
ETriggerEvent LastAttributeMenuInputProcessorTriggerEvent = ETriggerEvent::None;
};