UI框架调整,主界面重做 #16

初步调整
This commit is contained in:
2025-10-28 23:51:17 +08:00
parent 60596f2772
commit 239425c47d
40 changed files with 713 additions and 17 deletions

View File

@ -16,7 +16,7 @@ ManualIPAddress=
GlobalDefaultGameMode=/Game/Blueprint/Bp_BusyGameMode.Bp_BusyGameMode_C GlobalDefaultGameMode=/Game/Blueprint/Bp_BusyGameMode.Bp_BusyGameMode_C
GameInstanceClass=/Script/BusyRabbit.BusyGameInstance GameInstanceClass=/Script/BusyRabbit.BusyGameInstance
EditorStartupMap=/Game/Level/HomeLand.HomeLand EditorStartupMap=/Game/Level/HomeLand.HomeLand
GameDefaultMap=/Game/Level/HomeLand.HomeLand GameDefaultMap=/Game/Level/FalconPlain.FalconPlain
[/Script/Engine.RendererSettings] [/Script/Engine.RendererSettings]
r.Mobile.AntiAliasing=0 r.Mobile.AntiAliasing=0

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Content/UI/Level/bar.uasset Normal file

Binary file not shown.

Binary file not shown.

View File

@ -19,7 +19,7 @@
"**/bin": true, "**/bin": true,
"**/obj": true "**/obj": true
}, },
"dotnet.defaultSolution": "Script/${workspaceFolderBasename}.sln", "dotnet.defaultSolution": "Script/ManagedBusyRabbit/ManagedBusyRabbit.sln",
"omnisharp.enableRoslynAnalyzers": true, "omnisharp.enableRoslynAnalyzers": true,
"omnisharp.enableEditorConfigSupport": true, "omnisharp.enableEditorConfigSupport": true,
"csharp.suppressDotnetRestoreNotification": false "csharp.suppressDotnetRestoreNotification": false

View File

@ -47,9 +47,6 @@ public class UFoxUltimate : UBusyGameAbility
ASC = AbilitySystemLibrary.GetAbilitySystemComponent(Owner) as UBusyAbilitySystemComponent; ASC = AbilitySystemLibrary.GetAbilitySystemComponent(Owner) as UBusyAbilitySystemComponent;
if (FoxData == null || ASC == null) return false; if (FoxData == null || ASC == null) return false;
PrintString("asdafdasdf");
if (bIsEventBinded) return true; if (bIsEventBinded) return true;
TDelegate<GameplayTagAddOrRemoveDelegate> Delegate = new TDelegate<GameplayTagAddOrRemoveDelegate>(); TDelegate<GameplayTagAddOrRemoveDelegate> Delegate = new TDelegate<GameplayTagAddOrRemoveDelegate>();
Delegate.BindUFunction(this, "OnGamePlayTagAddOrRemove"); Delegate.BindUFunction(this, "OnGamePlayTagAddOrRemove");

View File

@ -0,0 +1,29 @@
using UnrealSharp.Engine;
using UnrealSharp.Attributes;
using UnrealSharp.BusyRabbit;
using UnrealSharp;
using UnrealSharp.UMG;
namespace Level.GameSettings;
[UClass]
public class ABusyLevelHud : APW_UIFrameworkHud
{
[UProperty(PropertyFlags.EditDefaultsOnly)]
public TSubclassOf<UPW_WidgetPanel> WidgetClass { set; get; }
protected override void BeginPlay()
{
base.BeginPlay();
}
protected override void OnResourceLoaded()
{
var widget = CreateWidget(WidgetClass);
UIManager.PushWidgetPanel(widget);
}
}

View File

@ -38,10 +38,7 @@ public class ABusyFoxRole : ABusyPlayerRole
protected override void EndPlay(EEndPlayReason endPlayReason) protected override void EndPlay(EEndPlayReason endPlayReason)
{ {
base.EndPlay(endPlayReason); base.EndPlay(endPlayReason);
PrintString("haha1");
MovementComponent.MoveDirectionChangedDelegate.Remove(OnRoleMoveDirectionChanged); MovementComponent.MoveDirectionChangedDelegate.Remove(OnRoleMoveDirectionChanged);
PrintString("haha2");
} }
[UFunction()] [UFunction()]

View File

@ -0,0 +1,76 @@
using UnrealSharp.Engine;
using UnrealSharp.Attributes;
using UnrealSharp.BusyRabbit;
using UnrealSharp.GameplayAbilities;
using UnrealSharp;
using UnrealSharp.CoreUObject;
namespace UI.Level.Controllers;
[UMultiDelegate]
public delegate void OnUIAttributeChange(FName AttributeName, float NewValue, float OldValue);
[UClass]
public class UBusyRoleStateController : UPW_UIController
{
[UProperty()]
public TMulticastDelegate<OnUIAttributeChange> OnAttributeChangeDelegate { get; set; }
protected override void OnUIControllerInitialized()
{
if (UGameplayStatics.GetPlayerController(0) is ALevelPlayerController PC)
{
ABusyPlayerRole Role = PC.ControlledRole;
if (AbilitySystemLibrary.GetAbilitySystemComponent(Role) is UBusyAbilitySystemComponent ASC)
{
RegisterAttributeListener(ASC, "Health");
RegisterAttributeListener(ASC, "Hunger");
}
}
}
public float GetControlledAttribute(FName AttributeName)
{
if (UGameplayStatics.GetPlayerController(0) is ALevelPlayerController PC)
{
ABusyPlayerRole Role = PC.ControlledRole;
if (AbilitySystemLibrary.GetAbilitySystemComponent(Role) is UBusyAbilitySystemComponent ASC)
{
FGameplayAttribute Attribute = UBusyAscLibrary.GetAttribute(Role.Attributes, AttributeName);
return ASC.GetGameplayAttributeValue(Attribute, out bool IsFound);
}
}
return 0;
}
public float GetRoleAttribute(ABusyPawnBase Pawn, FName Attribute)
{
return 0;
}
protected void RegisterAttributeListener(UBusyAbilitySystemComponent ASC, FName AttributeName)
{
TDelegate<OnBusyAttributeChange> Delegate = new TDelegate<OnBusyAttributeChange>();
Delegate.BindUFunction(this, "OnAttributeChange");
ASC.BindEventToAttributeChange(typeof(UBusyPlayerRoleAttributeSet), AttributeName, Delegate);
}
[UFunction()]
protected void OnAttributeChange(FName AttributeName, float NewValue, float OldValue)
{
OnAttributeChangeDelegate.Invoke(AttributeName, NewValue, OldValue);
}
protected override void OnUIControllerDestroy()
{
base.OnUIControllerDestroy();
}
}

View File

@ -0,0 +1,71 @@
using UnrealSharp.Attributes;
using UnrealSharp.BusyRabbit;
using UnrealSharp.UMG;
namespace UI.Level.StateBar;
[UClass]
public class UBusyWidgetHealthBar : UPW_MinimalWidget
{
[UProperty(PropertyFlags.EditAnywhere)]
public float Percent { get; set; }
[UProperty(PropertyFlags.EditAnywhere)]
public float Test { get; set; }
protected UProgressBar? HpBarHurt { get { return GetWidget("HpBarHurt") as UProgressBar; } }
protected UProgressBar? HpBarHealth { get { return GetWidget("HpBarHealth") as UProgressBar; } }
protected UProgressBar? HpBarNormal { get { return GetWidget("HpBarNormal") as UProgressBar; } }
protected USizeBox ? SizeboxMain { get { return GetWidget("SizeboxMain") as USizeBox; } }
[UProperty(PropertyFlags.EditAnywhere)]
public float MaxHp { get; set; }
[UProperty(PropertyFlags.EditAnywhere)]
public float CurHp { get; set; }
[UProperty(PropertyFlags.EditAnywhere)]
public float Width { get; set; }
[UProperty(PropertyFlags.EditAnywhere)]
public float Height { get; set; }
protected float LastHp = 200;
public override void PreConstruct(bool isDesignTime)
{
SetHpConfig(CurHp, MaxHp);
RefreshHealthBarDisplay();
}
public override void Construct()
{
base.Construct();
SetHpConfig(180, 200);
}
public void SetHpConfig(float CurHp, float MaxHp)
{
LastHp = CurHp;
this.CurHp = CurHp;
this.MaxHp = MaxHp;
RefreshHealthBarDisplay();
}
protected void RefreshHealthBarDisplay()
{
if (HpBarHealth == null || HpBarHurt == null || HpBarNormal == null || SizeboxMain == null)
{
return;
}
HpBarHurt.Visibility = ESlateVisibility.Collapsed;
HpBarHealth.Visibility = ESlateVisibility.Collapsed;
HpBarNormal.Percent = MaxHp != 0 ? (CurHp / MaxHp) : 0;
SizeboxMain.WidthOverride = Width;
SizeboxMain.HeightOverride = Height;
}
}

View File

@ -0,0 +1,36 @@
using UnrealSharp.Engine;
using UnrealSharp.Attributes;
using UnrealSharp.BusyRabbit;
using UnrealSharp.UMG;
namespace UI.Level.StateBar;
[UClass]
public class UBusyWidgetSatietyBar : UPW_MinimalWidget
{
protected UProgressBar? SatietyBar { get { return GetWidget("SatietyBar") as UProgressBar; } }
protected float CurrSatiety;
protected float MaxSatiety;
public void SetSatietyConfig(float CurrSatiety, float MaxSatiety)
{
this.MaxSatiety = MaxSatiety;
this.CurrSatiety = CurrSatiety;
RefreshDisplay();
}
public void OnSatietyChanged(float CurSatiety)
{
this.CurrSatiety = CurSatiety;
RefreshDisplay();
}
public void RefreshDisplay()
{
float Percent = MaxSatiety > 0 ? CurrSatiety / MaxSatiety : 0;
if (SatietyBar != null)
{
SatietyBar.Percent = Percent;
}
}
}

View File

@ -0,0 +1,55 @@
using UnrealSharp.Engine;
using UI.Level.Controllers;
using UnrealSharp.Attributes;
using UnrealSharp.BusyRabbit;
using UnrealSharp;
namespace UI.Level.StateBar;
[UClass]
public class UBusyWidgetStateBar : UPW_MinimalWidget
{
protected UBusyWidgetHealthBar? WBP_HealthBar { get { return GetWidget("WBP_HealthBar") as UBusyWidgetHealthBar; } }
protected UBusyWidgetSatietyBar? WBP_SatietyBar { get { return GetWidget("WBP_SatietyBar") as UBusyWidgetSatietyBar; } }
protected UBusyRoleStateController? UIController;
public override void Construct()
{
base.Construct();
WBP_SatietyBar.SetSatietyConfig(100, 200);
UIController = UUIFunctionLibrary.GetUIController(this, "RoleState") as UBusyRoleStateController;
InitRoleAttribute();
UIController.OnAttributeChangeDelegate += OnAttributeChanged;
}
public void InitRoleAttribute()
{
float CurHealth = UIController.GetControlledAttribute("Health");
float MaxHealth = UIController.GetControlledAttribute("MaxHealth");
float CurSatiety = UIController.GetControlledAttribute("Hunger");
float MaxSatiety = UIController.GetControlledAttribute("MaxHunger");
WBP_HealthBar.SetHpConfig(CurHealth, MaxHealth);
WBP_SatietyBar.SetSatietyConfig(CurSatiety, MaxSatiety);
}
public override void Destruct()
{
base.Destruct();
UIController.OnAttributeChangeDelegate -= OnAttributeChanged;
}
[UFunction()]
protected void OnAttributeChanged(FName AttributeName, float NewValue, float OldValue)
{
if (AttributeName == "Hunger")
{
WBP_SatietyBar.OnSatietyChanged(NewValue);
}
}
}

View File

@ -4,6 +4,7 @@
#include "AbilitySystemGlobals.h" #include "AbilitySystemGlobals.h"
#include "GameplayEffectTypes.h" #include "GameplayEffectTypes.h"
#include "Gas/BusyGameAbility.h" #include "Gas/BusyGameAbility.h"
#include "Level/Actor/BusyPawnBase.h"
UBusyAbilityDataAssetBase* UBusyAscLibrary::GetAbilityDataAssetByEffect(const FGameplayEffectSpec& Spec) UBusyAbilityDataAssetBase* UBusyAscLibrary::GetAbilityDataAssetByEffect(const FGameplayEffectSpec& Spec)
{ {
@ -28,3 +29,12 @@ FGameplayEffectSpecHandle UBusyAscLibrary::MakeGameplayEffectSpecHandle(const UA
FGameplayEffectSpec* NewSpec = new FGameplayEffectSpec(Effect, ContextHandle, Level); FGameplayEffectSpec* NewSpec = new FGameplayEffectSpec(Effect, ContextHandle, Level);
return FGameplayEffectSpecHandle(NewSpec); return FGameplayEffectSpecHandle(NewSpec);
} }
FGameplayAttribute UBusyAscLibrary::GetAttribute(const UBusyPawnAttributeSet* AttributeSet, const FName& AttributeName)
{
if (FProperty* Prop = FindFieldChecked<FProperty>(AttributeSet->GetClass(), AttributeName))
{
return Prop;
}
return nullptr;
}

View File

@ -0,0 +1,19 @@
#include "BlueprintLibrary/UIFunctionLibrary.h"
#include "UIFramework/UIFrameworkHud.h"
UPW_UIController* UUIFunctionLibrary::GetUIController(const UObject* Object, const FName& Name)
{
if (Object == nullptr) return nullptr;
const UWorld* World = Object->GetWorld();
if (World == nullptr) return nullptr;
const APlayerController* PC = World->GetFirstPlayerController();
if (PC == nullptr) return nullptr;
if (APW_UIFrameworkHud* Hud = Cast<APW_UIFrameworkHud>(PC->GetHUD()))
{
return Hud->GetUIController(Name);
}
return nullptr;
}

View File

@ -1 +1,16 @@
#include "Level/Actor/Components/BusyAbilitySystemComponent.h" #include "Level/Actor/Components/BusyAbilitySystemComponent.h"
void UBusyAbilitySystemComponent::BindEventToAttributeChange(const UClass* AttributeSetClass, const FName& AttributeName, FOnBusyAttributeChange Delegate)
{
FProperty* Prop = FindFieldChecked<FProperty>(AttributeSetClass, AttributeName);
if (Prop == nullptr)
{
return;
}
FOnGameplayAttributeValueChange &OnAttributeChange = GetGameplayAttributeValueChangeDelegate(Prop);
OnAttributeChange.AddLambda([AttributeName, Delegate](const FOnAttributeChangeData& Data)
{
Delegate.ExecuteIfBound(AttributeName, Data.NewValue, Data.OldValue);
});
}

View File

@ -0,0 +1,6 @@
#include "UIFramework/MinimalWidget.h"
UWidget* UPW_MinimalWidget::GetWidget(const FName& Name)const
{
return GetWidgetFromName(Name);
}

View File

@ -0,0 +1,22 @@
#include "UIFramework/RootWidget.h"
#include "Blueprint/WidgetTree.h"
#include "UIFramework/WidgetPanel.h"
#include "Components/Overlay.h"
#include "Components/OverlaySlot.h"
bool UPW_RootWidget::PushWidget(UPW_WidgetPanel* Widget)const
{
if (UOverlaySlot* OverlaySlot = Cast<UOverlaySlot>(MainOverlay->AddChild(Widget)))
{
OverlaySlot->SetHorizontalAlignment(HAlign_Fill);
OverlaySlot->SetVerticalAlignment(VAlign_Fill);
return true;
}
return false;
}
bool UPW_RootWidget::RemoveWidget(UPW_WidgetPanel* Widget)const
{
return MainOverlay->RemoveChild(Widget);
}

View File

@ -0,0 +1,21 @@
#include "UIFramework/UIController.h"
void UPW_UIController::InitUIController(APW_UIFrameworkHud* UIHud)
{
Hud = UIHud;
OnUIControllerInitialized();
}
void UPW_UIController::DestroyUIController()
{
OnUIControllerDestroy();
}
void UPW_UIController::OnUIControllerInitialized_Implementation()
{
}
void UPW_UIController::OnUIControllerDestroy_Implementation()
{
}

View File

@ -0,0 +1,83 @@
#include "UIFramework/UIFrameworkHud.h"
#include "UIFramework/RootWidget.h"
#include "UIFramework/UIController.h"
DEFINE_LOG_CATEGORY(LogUIHud)
APW_UIFrameworkHud::APW_UIFrameworkHud()
{
UIManager = CreateDefaultSubobject<UPW_UIManager>(TEXT("UIManager"));
}
void APW_UIFrameworkHud::BeginPlay()
{
if (RootWidgetClass)
{
UPW_RootWidget* Root = NewObject<UPW_RootWidget>(this, RootWidgetClass, FName("RootWidget"));
UIManager->AttachUIDisplay(Root);
}
for (const TPair Pair : UIControllerClasses)
{
TSoftClassPtr<UPW_UIController> ControllerClass = Pair.Value;
if (ControllerClass.IsNull()) continue;
auto Delegate = FLoadSoftObjectPathAsyncDelegate::CreateLambda([this, Pair](const FSoftObjectPath& Path, UObject* Object)
{
if (const UClass* UIControllerClass = Cast<UClass>(Object))
{
if (UPW_UIController* NewController = NewObject<UPW_UIController>(this, UIControllerClass))
{
UIControllers.Add(Pair.Key, NewController);
NewController->InitUIController(this);
}
}
TryNotifyResourceLoaded();
});
if (ControllerClass.LoadAsync(Delegate) == -1)
{
UE_LOG(LogUIHud, Error, TEXT("APW_UIFrameworkHud::BeginPlay can't load class: %s"), *ControllerClass.GetAssetName());
}
}
Super::BeginPlay();
}
void APW_UIFrameworkHud::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
UIManager->DetachUIDisplay();
for (const TPair Pair: UIControllers)
{
if (UPW_UIController* Controller = Pair.Value)
{
Controller->DestroyUIController();
}
}
UIControllers.Empty();
Super::EndPlay(EndPlayReason);
}
UPW_UIController* APW_UIFrameworkHud::GetUIController(const FName& Name)
{
if (UPW_UIController** ControllerPtr = UIControllers.Find(Name))
{
return *ControllerPtr;
}
return nullptr;
}
void APW_UIFrameworkHud::TryNotifyResourceLoaded()
{
if (UIControllers.Num() == UIControllerClasses.Num())
{
OnResourceLoaded();
}
}
void APW_UIFrameworkHud::OnResourceLoaded_Implementation()
{
}

View File

@ -0,0 +1,60 @@
#include "UIFramework/UIManager.h"
#include "Blueprint/UserWidget.h"
#include "UIFramework/RootWidget.h"
#include "UIFramework/UIFrameworkHud.h"
bool UPW_UIManager::AttachUIDisplay(UPW_RootWidget* InRootWidget)
{
if (InRootWidget)
{
RootWidget = InRootWidget;
InRootWidget->AddToViewport();
return true;
}
return false;
}
void UPW_UIManager::DetachUIDisplay()const
{
if (RootWidget.Get() != nullptr)
{
RootWidget->RemoveFromParent();
}
}
void UPW_UIManager::SetRootWidget(UPW_RootWidget* NewRootWidget)
{
RootWidget = NewRootWidget;
}
UPW_UIManager* UPW_UIManager::Get(UWorld* World)
{
if (World == nullptr) return nullptr;
const APlayerController* PC = World->GetFirstPlayerController();
if (PC == nullptr) return nullptr;
if (const APW_UIFrameworkHud * Hud = Cast<APW_UIFrameworkHud>(PC->GetHUD()))
{
return Hud->GetUIManager();
}
return nullptr;
}
bool UPW_UIManager::PushWidgetPanel(UPW_WidgetPanel* Panel)
{
if (RootWidget.Get() == nullptr) return false;
if (WidgetPanelStack.Contains(Panel))
{
WidgetPanelStack.Remove(Panel);
}
WidgetPanelStack.Push(Panel);
RootWidget->PushWidget(Panel);
return true;
}
void UPW_UIManager::PopWidgetPanel(UPW_WidgetPanel* Panel)
{
}

View File

@ -0,0 +1 @@
#include "UIFramework/WidgetPanel.h"

View File

@ -5,6 +5,7 @@
class UGameplayEffect; class UGameplayEffect;
struct FGameplayEffectSpec; struct FGameplayEffectSpec;
class UBusyPawnAttributeSet;
class UBusyAbilityDataAssetBase; class UBusyAbilityDataAssetBase;
UCLASS() UCLASS()
@ -20,4 +21,8 @@ public:
UFUNCTION(BlueprintCallable) UFUNCTION(BlueprintCallable)
static FGameplayEffectSpecHandle MakeGameplayEffectSpecHandle(const UAbilitySystemComponent* Asc, const UGameplayEffect* Effect, const float Level); static FGameplayEffectSpecHandle MakeGameplayEffectSpecHandle(const UAbilitySystemComponent* Asc, const UGameplayEffect* Effect, const float Level);
UFUNCTION(BlueprintCallable)
static FGameplayAttribute GetAttribute(const UBusyPawnAttributeSet* AttributeSet, const FName& AttributeName);
}; };

View File

@ -0,0 +1,15 @@
#pragma once
#include "UIFunctionLibrary.generated.h"
class UPW_UIController;
UCLASS(BlueprintType)
class UUIFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "UIFunctionLibrary")
static UPW_UIController* GetUIController(const UObject* Object, const FName& Name);
};

View File

@ -70,7 +70,7 @@ public:
* *
*/ */
UCLASS() UCLASS()
class BUSYRABBIT_API UPW_UserWidget : public UPW_SimpleWidget{ class BUSYRABBIT_API UPW_UserWidget : public UUserWidget{
GENERATED_BODY() GENERATED_BODY()
public: public:
// UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, DisplayName="是否全局唯一") // UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, DisplayName="是否全局唯一")

View File

@ -12,7 +12,7 @@ class UBusyPawnMovementComponent;
DECLARE_DYNAMIC_DELEGATE_TwoParams(FGameplayTagAddOrRemoveDelegate, const FGameplayTag&, Tag, const int32, Value); DECLARE_DYNAMIC_DELEGATE_TwoParams(FGameplayTagAddOrRemoveDelegate, const FGameplayTag&, Tag, const int32, Value);
#define MY_ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \ #define BUSY_ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \ GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \ GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \ GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
@ -27,28 +27,29 @@ class UBusyPawnAttributeSet : public UAttributeSet
GENERATED_BODY() GENERATED_BODY()
public: public:
public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData Health; FGameplayAttributeData Health;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Health); BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Health);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData MaxHealth; FGameplayAttributeData MaxHealth;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MaxHealth); BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MaxHealth);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData MoveSpeed; FGameplayAttributeData MoveSpeed;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MoveSpeed); BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MoveSpeed);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData Damage; FGameplayAttributeData Damage;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Damage); BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Damage);
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes")
FGameplayAttributeData Defense; FGameplayAttributeData Defense;
MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Defense); BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Defense);
}; };
#undef MY_ATTRIBUTE_ACCESSORS #undef BUSY_ATTRIBUTE_ACCESSORS
UCLASS() UCLASS()
@ -103,7 +104,7 @@ public:
FName PawnName; FName PawnName;
protected: public:
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
TObjectPtr<UBusyPawnAttributeSet> Attributes = nullptr; TObjectPtr<UBusyPawnAttributeSet> Attributes = nullptr;

View File

@ -2,9 +2,13 @@
#include "AbilitySystemComponent.h" #include "AbilitySystemComponent.h"
#include "BusyAbilitySystemComponent.generated.h" #include "BusyAbilitySystemComponent.generated.h"
DECLARE_DYNAMIC_DELEGATE_ThreeParams(FOnBusyAttributeChange, const FName&, AttributeName, float, NewValue, float, OldValue);
UCLASS() UCLASS()
class UBusyAbilitySystemComponent : public UAbilitySystemComponent class UBusyAbilitySystemComponent : public UAbilitySystemComponent
{ {
GENERATED_BODY() GENERATED_BODY()
UFUNCTION(BlueprintCallable)
void BindEventToAttributeChange(const UClass* AttributeSetClass, const FName& AttributeName, FOnBusyAttributeChange Delegate);
}; };

View File

@ -0,0 +1,17 @@
#pragma once
#include "Blueprint/UserWidget.h"
#include "MinimalWidget.generated.h"
UCLASS(Blueprintable, BlueprintType)
class UPW_MinimalWidget : public UUserWidget
{
GENERATED_BODY()
public:
UFUNCTION(BlueprintCallable, Category = "Widget")
UWidget* GetWidget(const FName& Name)const;
};

View File

@ -0,0 +1,24 @@
#pragma once
#include "Blueprint/UserWidget.h"
#include "RootWidget.generated.h"
class UOverlay;
class UPW_WidgetPanel;
UCLASS()
class UPW_RootWidget : public UUserWidget
{
GENERATED_BODY()
public:
bool PushWidget(UPW_WidgetPanel* Widget)const;
bool RemoveWidget(UPW_WidgetPanel* Widget)const;
protected:
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Widget", meta=(BindWidget))
TObjectPtr<UOverlay> MainOverlay;
};

View File

@ -0,0 +1,30 @@
#pragma once
#include "UIController.generated.h"
class APW_UIFrameworkHud;
UCLASS(Blueprintable, BlueprintType)
class UPW_UIController : public UObject
{
GENERATED_BODY()
public:
void InitUIController(APW_UIFrameworkHud* UIHud);
void DestroyUIController();
protected:
UFUNCTION(BlueprintNativeEvent)
void OnUIControllerInitialized();
UFUNCTION(BlueprintNativeEvent)
void OnUIControllerDestroy();
protected:
UPROPERTY()
TObjectPtr<APW_UIFrameworkHud> Hud;
UPROPERTY()
TObjectPtr<APlayerController> PC;
};

View File

@ -0,0 +1,55 @@
#pragma once
#include "GameFramework/HUD.h"
#include "UIFramework/UIManager.h"
#include "UIFrameworkHud.generated.h"
DECLARE_LOG_CATEGORY_EXTERN(LogUIHud, Log, All);
class UPW_UIController;
UCLASS(Blueprintable, BlueprintType)
class APW_UIFrameworkHud : public AHUD
{
GENERATED_BODY()
public:
APW_UIFrameworkHud();
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
public:
UPW_UIController* GetUIController(const FName& Name);
public:
UPW_UIManager* GetUIManager()const {return UIManager.Get();}
protected:
void TryNotifyResourceLoaded();
protected:
UFUNCTION(BlueprintNativeEvent)
void OnResourceLoaded();
protected:
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TSubclassOf<UPW_RootWidget> RootWidgetClass;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
TMap<FName, TSoftClassPtr<UPW_UIController>> UIControllerClasses;
protected:
UPROPERTY()
TObjectPtr<UPW_UIManager> UIManager;
UPROPERTY()
TMap<FName, UPW_UIController*> UIControllers;
};

View File

@ -0,0 +1,34 @@
#pragma once
#include "UIManager.generated.h"
class UPW_RootWidget;
class UPW_WidgetPanel;
UCLASS(BlueprintType)
class UPW_UIManager : public UObject
{
GENERATED_BODY()
public:
bool AttachUIDisplay(UPW_RootWidget* InRootWidget);
void DetachUIDisplay()const;
void SetRootWidget(UPW_RootWidget* NewRootWidget);
public:
UFUNCTION(BlueprintCallable)
static UPW_UIManager* Get(UWorld* World);
UFUNCTION(BlueprintCallable)
bool PushWidgetPanel(UPW_WidgetPanel* Panel);
UFUNCTION(BlueprintCallable)
void PopWidgetPanel(UPW_WidgetPanel* Panel);
protected:
UPROPERTY()
TArray<UPW_WidgetPanel*> WidgetPanelStack;
UPROPERTY()
TObjectPtr<UPW_RootWidget> RootWidget;
};

View File

@ -0,0 +1,13 @@
#pragma once
#include "UIFramework/MinimalWidget.h"
#include "WidgetPanel.generated.h"
UCLASS(BlueprintType, Blueprintable)
class UPW_WidgetPanel : public UPW_MinimalWidget
{
GENERATED_BODY()
public:
};