diff --git a/Config/DefaultEngine.ini b/Config/DefaultEngine.ini index a6c9c09..05b4eca 100644 --- a/Config/DefaultEngine.ini +++ b/Config/DefaultEngine.ini @@ -16,7 +16,7 @@ ManualIPAddress= GlobalDefaultGameMode=/Game/Blueprint/Bp_BusyGameMode.Bp_BusyGameMode_C GameInstanceClass=/Script/BusyRabbit.BusyGameInstance EditorStartupMap=/Game/Level/HomeLand.HomeLand -GameDefaultMap=/Game/Level/HomeLand.HomeLand +GameDefaultMap=/Game/Level/FalconPlain.FalconPlain [/Script/Engine.RendererSettings] r.Mobile.AntiAliasing=0 diff --git a/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset b/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset index a4a4b84..47845b2 100644 Binary files a/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset and b/Content/Blueprint/Level/GameMode/BP_BusyLevelGameMode.uasset differ diff --git a/Content/UI/BP_BusyRootWidget.uasset b/Content/UI/BP_BusyRootWidget.uasset new file mode 100644 index 0000000..3bb0277 Binary files /dev/null and b/Content/UI/BP_BusyRootWidget.uasset differ diff --git a/Content/UI/Level/BP_BusyLevelHud.uasset b/Content/UI/Level/BP_BusyLevelHud.uasset new file mode 100644 index 0000000..41be366 Binary files /dev/null and b/Content/UI/Level/BP_BusyLevelHud.uasset differ diff --git a/Content/UI/Level/StateBar/WBP_HealthBar.uasset b/Content/UI/Level/StateBar/WBP_HealthBar.uasset new file mode 100644 index 0000000..b1a0378 Binary files /dev/null and b/Content/UI/Level/StateBar/WBP_HealthBar.uasset differ diff --git a/Content/UI/Level/StateBar/WBP_RoleHead.uasset b/Content/UI/Level/StateBar/WBP_RoleHead.uasset new file mode 100644 index 0000000..13b39fa Binary files /dev/null and b/Content/UI/Level/StateBar/WBP_RoleHead.uasset differ diff --git a/Content/UI/Level/StateBar/WBP_SatietyBar.uasset b/Content/UI/Level/StateBar/WBP_SatietyBar.uasset new file mode 100644 index 0000000..4d41800 Binary files /dev/null and b/Content/UI/Level/StateBar/WBP_SatietyBar.uasset differ diff --git a/Content/UI/Level/StateBar/WBP_StateBar.uasset b/Content/UI/Level/StateBar/WBP_StateBar.uasset new file mode 100644 index 0000000..2e6e67c Binary files /dev/null and b/Content/UI/Level/StateBar/WBP_StateBar.uasset differ diff --git a/Content/UI/Level/UIControllers/BP_RoleStateController.uasset b/Content/UI/Level/UIControllers/BP_RoleStateController.uasset new file mode 100644 index 0000000..89b0bc2 Binary files /dev/null and b/Content/UI/Level/UIControllers/BP_RoleStateController.uasset differ diff --git a/Content/UI/Level/WBP_MainPanel.uasset b/Content/UI/Level/WBP_MainPanel.uasset new file mode 100644 index 0000000..3afd04f Binary files /dev/null and b/Content/UI/Level/WBP_MainPanel.uasset differ diff --git a/Content/UI/Level/bar.uasset b/Content/UI/Level/bar.uasset new file mode 100644 index 0000000..34cdd6d Binary files /dev/null and b/Content/UI/Level/bar.uasset differ diff --git a/Content/UI/Level/bar2.uasset b/Content/UI/Level/bar2.uasset new file mode 100644 index 0000000..cc0567a Binary files /dev/null and b/Content/UI/Level/bar2.uasset differ diff --git a/Script/BusyRabbit-CSharp.code-workspace b/Script/BusyRabbit-CSharp.code-workspace index 551957e..a38b9cd 100644 --- a/Script/BusyRabbit-CSharp.code-workspace +++ b/Script/BusyRabbit-CSharp.code-workspace @@ -19,7 +19,7 @@ "**/bin": true, "**/obj": true }, - "dotnet.defaultSolution": "Script/${workspaceFolderBasename}.sln", + "dotnet.defaultSolution": "Script/ManagedBusyRabbit/ManagedBusyRabbit.sln", "omnisharp.enableRoslynAnalyzers": true, "omnisharp.enableEditorConfigSupport": true, "csharp.suppressDotnetRestoreNotification": false diff --git a/Script/ManagedBusyRabbit/GameAbilitySystem/Ability/Role/Fox/FoxUltimate.cs b/Script/ManagedBusyRabbit/GameAbilitySystem/Ability/Role/Fox/FoxUltimate.cs index ec8c37c..eb66981 100644 --- a/Script/ManagedBusyRabbit/GameAbilitySystem/Ability/Role/Fox/FoxUltimate.cs +++ b/Script/ManagedBusyRabbit/GameAbilitySystem/Ability/Role/Fox/FoxUltimate.cs @@ -47,9 +47,6 @@ public class UFoxUltimate : UBusyGameAbility ASC = AbilitySystemLibrary.GetAbilitySystemComponent(Owner) as UBusyAbilitySystemComponent; if (FoxData == null || ASC == null) return false; - PrintString("asdafdasdf"); - - if (bIsEventBinded) return true; TDelegate Delegate = new TDelegate(); Delegate.BindUFunction(this, "OnGamePlayTagAddOrRemove"); diff --git a/Script/ManagedBusyRabbit/Level/GameSettings/BusyLevelHud.cs b/Script/ManagedBusyRabbit/Level/GameSettings/BusyLevelHud.cs new file mode 100644 index 0000000..ed8e437 --- /dev/null +++ b/Script/ManagedBusyRabbit/Level/GameSettings/BusyLevelHud.cs @@ -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 WidgetClass { set; get; } + + + protected override void BeginPlay() + { + base.BeginPlay(); + + } + + protected override void OnResourceLoaded() + { + + var widget = CreateWidget(WidgetClass); + UIManager.PushWidgetPanel(widget); + } + +} \ No newline at end of file diff --git a/Script/ManagedBusyRabbit/Level/Role/BusyFoxRole.cs b/Script/ManagedBusyRabbit/Level/Role/BusyFoxRole.cs index 392a749..5be6fe1 100644 --- a/Script/ManagedBusyRabbit/Level/Role/BusyFoxRole.cs +++ b/Script/ManagedBusyRabbit/Level/Role/BusyFoxRole.cs @@ -38,10 +38,7 @@ public class ABusyFoxRole : ABusyPlayerRole protected override void EndPlay(EEndPlayReason endPlayReason) { base.EndPlay(endPlayReason); - PrintString("haha1"); MovementComponent.MoveDirectionChangedDelegate.Remove(OnRoleMoveDirectionChanged); - PrintString("haha2"); - } [UFunction()] diff --git a/Script/ManagedBusyRabbit/UI/Level/Controllers/BusyRoleStateController.cs b/Script/ManagedBusyRabbit/UI/Level/Controllers/BusyRoleStateController.cs new file mode 100644 index 0000000..3f7519e --- /dev/null +++ b/Script/ManagedBusyRabbit/UI/Level/Controllers/BusyRoleStateController.cs @@ -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 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 Delegate = new TDelegate(); + 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(); + } +} \ No newline at end of file diff --git a/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyHealthBar.cs b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyHealthBar.cs new file mode 100644 index 0000000..423e8bb --- /dev/null +++ b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyHealthBar.cs @@ -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; + } + +} \ No newline at end of file diff --git a/Script/ManagedBusyRabbit/UI/Level/StateBar/BusySatietyBar.cs b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusySatietyBar.cs new file mode 100644 index 0000000..2e8b818 --- /dev/null +++ b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusySatietyBar.cs @@ -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; + } + } +} diff --git a/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyStateBar.cs b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyStateBar.cs new file mode 100644 index 0000000..b860a1b --- /dev/null +++ b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyStateBar.cs @@ -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); + } + } +} diff --git a/Source/BusyRabbit/Private/BlueprintLibrary/BusyAscLibrary.cpp b/Source/BusyRabbit/Private/BlueprintLibrary/BusyAscLibrary.cpp index 08d155a..93344aa 100644 --- a/Source/BusyRabbit/Private/BlueprintLibrary/BusyAscLibrary.cpp +++ b/Source/BusyRabbit/Private/BlueprintLibrary/BusyAscLibrary.cpp @@ -4,6 +4,7 @@ #include "AbilitySystemGlobals.h" #include "GameplayEffectTypes.h" #include "Gas/BusyGameAbility.h" +#include "Level/Actor/BusyPawnBase.h" UBusyAbilityDataAssetBase* UBusyAscLibrary::GetAbilityDataAssetByEffect(const FGameplayEffectSpec& Spec) { @@ -28,3 +29,12 @@ FGameplayEffectSpecHandle UBusyAscLibrary::MakeGameplayEffectSpecHandle(const UA FGameplayEffectSpec* NewSpec = new FGameplayEffectSpec(Effect, ContextHandle, Level); return FGameplayEffectSpecHandle(NewSpec); } + +FGameplayAttribute UBusyAscLibrary::GetAttribute(const UBusyPawnAttributeSet* AttributeSet, const FName& AttributeName) +{ + if (FProperty* Prop = FindFieldChecked(AttributeSet->GetClass(), AttributeName)) + { + return Prop; + } + return nullptr; +} diff --git a/Source/BusyRabbit/Private/BlueprintLibrary/UIFunctionLibrary.cpp b/Source/BusyRabbit/Private/BlueprintLibrary/UIFunctionLibrary.cpp new file mode 100644 index 0000000..f9c84d9 --- /dev/null +++ b/Source/BusyRabbit/Private/BlueprintLibrary/UIFunctionLibrary.cpp @@ -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(PC->GetHUD())) + { + return Hud->GetUIController(Name); + } + + return nullptr; + +} diff --git a/Source/BusyRabbit/Private/Level/Actor/Components/BusyAbilitySystemComponent.cpp b/Source/BusyRabbit/Private/Level/Actor/Components/BusyAbilitySystemComponent.cpp index 86507c8..c96f323 100644 --- a/Source/BusyRabbit/Private/Level/Actor/Components/BusyAbilitySystemComponent.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/Components/BusyAbilitySystemComponent.cpp @@ -1 +1,16 @@ #include "Level/Actor/Components/BusyAbilitySystemComponent.h" + +void UBusyAbilitySystemComponent::BindEventToAttributeChange(const UClass* AttributeSetClass, const FName& AttributeName, FOnBusyAttributeChange Delegate) +{ + FProperty* Prop = FindFieldChecked(AttributeSetClass, AttributeName); + if (Prop == nullptr) + { + return; + } + FOnGameplayAttributeValueChange &OnAttributeChange = GetGameplayAttributeValueChangeDelegate(Prop); + + OnAttributeChange.AddLambda([AttributeName, Delegate](const FOnAttributeChangeData& Data) + { + Delegate.ExecuteIfBound(AttributeName, Data.NewValue, Data.OldValue); + }); +} diff --git a/Source/BusyRabbit/Private/UIFramework/MinimalWidget.cpp b/Source/BusyRabbit/Private/UIFramework/MinimalWidget.cpp new file mode 100644 index 0000000..33e0673 --- /dev/null +++ b/Source/BusyRabbit/Private/UIFramework/MinimalWidget.cpp @@ -0,0 +1,6 @@ +#include "UIFramework/MinimalWidget.h" + +UWidget* UPW_MinimalWidget::GetWidget(const FName& Name)const +{ + return GetWidgetFromName(Name); +} diff --git a/Source/BusyRabbit/Private/UIFramework/RootWidget.cpp b/Source/BusyRabbit/Private/UIFramework/RootWidget.cpp new file mode 100644 index 0000000..dfb882f --- /dev/null +++ b/Source/BusyRabbit/Private/UIFramework/RootWidget.cpp @@ -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(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); +} diff --git a/Source/BusyRabbit/Private/UIFramework/UIController.cpp b/Source/BusyRabbit/Private/UIFramework/UIController.cpp new file mode 100644 index 0000000..9094336 --- /dev/null +++ b/Source/BusyRabbit/Private/UIFramework/UIController.cpp @@ -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() +{ +} diff --git a/Source/BusyRabbit/Private/UIFramework/UIFrameworkHud.cpp b/Source/BusyRabbit/Private/UIFramework/UIFrameworkHud.cpp new file mode 100644 index 0000000..011d189 --- /dev/null +++ b/Source/BusyRabbit/Private/UIFramework/UIFrameworkHud.cpp @@ -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(TEXT("UIManager")); +} + +void APW_UIFrameworkHud::BeginPlay() +{ + if (RootWidgetClass) + { + UPW_RootWidget* Root = NewObject(this, RootWidgetClass, FName("RootWidget")); + UIManager->AttachUIDisplay(Root); + } + + for (const TPair Pair : UIControllerClasses) + { + TSoftClassPtr ControllerClass = Pair.Value; + if (ControllerClass.IsNull()) continue; + + auto Delegate = FLoadSoftObjectPathAsyncDelegate::CreateLambda([this, Pair](const FSoftObjectPath& Path, UObject* Object) + { + if (const UClass* UIControllerClass = Cast(Object)) + { + if (UPW_UIController* NewController = NewObject(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() +{ +} + diff --git a/Source/BusyRabbit/Private/UIFramework/UIManager.cpp b/Source/BusyRabbit/Private/UIFramework/UIManager.cpp new file mode 100644 index 0000000..f13bbd1 --- /dev/null +++ b/Source/BusyRabbit/Private/UIFramework/UIManager.cpp @@ -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(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) +{ +} diff --git a/Source/BusyRabbit/Private/UIFramework/WidgetPanel.cpp b/Source/BusyRabbit/Private/UIFramework/WidgetPanel.cpp new file mode 100644 index 0000000..c57bcc3 --- /dev/null +++ b/Source/BusyRabbit/Private/UIFramework/WidgetPanel.cpp @@ -0,0 +1 @@ +#include "UIFramework/WidgetPanel.h" diff --git a/Source/BusyRabbit/Public/BlueprintLibrary/BusyAscLibrary.h b/Source/BusyRabbit/Public/BlueprintLibrary/BusyAscLibrary.h index 8e912ed..c5c77fb 100644 --- a/Source/BusyRabbit/Public/BlueprintLibrary/BusyAscLibrary.h +++ b/Source/BusyRabbit/Public/BlueprintLibrary/BusyAscLibrary.h @@ -5,6 +5,7 @@ class UGameplayEffect; struct FGameplayEffectSpec; +class UBusyPawnAttributeSet; class UBusyAbilityDataAssetBase; UCLASS() @@ -20,4 +21,8 @@ public: UFUNCTION(BlueprintCallable) static FGameplayEffectSpecHandle MakeGameplayEffectSpecHandle(const UAbilitySystemComponent* Asc, const UGameplayEffect* Effect, const float Level); + + + UFUNCTION(BlueprintCallable) + static FGameplayAttribute GetAttribute(const UBusyPawnAttributeSet* AttributeSet, const FName& AttributeName); }; diff --git a/Source/BusyRabbit/Public/BlueprintLibrary/UIFunctionLibrary.h b/Source/BusyRabbit/Public/BlueprintLibrary/UIFunctionLibrary.h new file mode 100644 index 0000000..988dab7 --- /dev/null +++ b/Source/BusyRabbit/Public/BlueprintLibrary/UIFunctionLibrary.h @@ -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); + +}; diff --git a/Source/BusyRabbit/Public/Core/PW_UserWidget.h b/Source/BusyRabbit/Public/Core/PW_UserWidget.h index a429fe8..df15c84 100644 --- a/Source/BusyRabbit/Public/Core/PW_UserWidget.h +++ b/Source/BusyRabbit/Public/Core/PW_UserWidget.h @@ -70,7 +70,7 @@ public: * */ UCLASS() -class BUSYRABBIT_API UPW_UserWidget : public UPW_SimpleWidget{ +class BUSYRABBIT_API UPW_UserWidget : public UUserWidget{ GENERATED_BODY() public: // UPROPERTY(BlueprintReadOnly, EditDefaultsOnly, DisplayName="是否全局唯一") diff --git a/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h b/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h index e296956..217a8e4 100644 --- a/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h +++ b/Source/BusyRabbit/Public/Level/Actor/BusyPawnBase.h @@ -12,7 +12,7 @@ class UBusyPawnMovementComponent; 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_VALUE_GETTER(PropertyName) \ GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \ @@ -27,28 +27,29 @@ class UBusyPawnAttributeSet : public UAttributeSet GENERATED_BODY() public: +public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData Health; - MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Health); + BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Health); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData MaxHealth; - MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MaxHealth); + BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MaxHealth); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData MoveSpeed; - MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MoveSpeed); + BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, MoveSpeed); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData Damage; - MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Damage); + BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Damage); UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData Defense; - MY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Defense); + BUSY_ATTRIBUTE_ACCESSORS(UBusyPawnAttributeSet, Defense); }; -#undef MY_ATTRIBUTE_ACCESSORS +#undef BUSY_ATTRIBUTE_ACCESSORS UCLASS() @@ -103,7 +104,7 @@ public: FName PawnName; -protected: +public: UPROPERTY(EditDefaultsOnly, BlueprintReadOnly) TObjectPtr Attributes = nullptr; diff --git a/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h b/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h index e8e20ef..c4d4f83 100644 --- a/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h +++ b/Source/BusyRabbit/Public/Level/Actor/Components/BusyAbilitySystemComponent.h @@ -2,9 +2,13 @@ #include "AbilitySystemComponent.h" #include "BusyAbilitySystemComponent.generated.h" +DECLARE_DYNAMIC_DELEGATE_ThreeParams(FOnBusyAttributeChange, const FName&, AttributeName, float, NewValue, float, OldValue); UCLASS() class UBusyAbilitySystemComponent : public UAbilitySystemComponent { GENERATED_BODY() + + UFUNCTION(BlueprintCallable) + void BindEventToAttributeChange(const UClass* AttributeSetClass, const FName& AttributeName, FOnBusyAttributeChange Delegate); }; diff --git a/Source/BusyRabbit/Public/UIFramework/MinimalWidget.h b/Source/BusyRabbit/Public/UIFramework/MinimalWidget.h new file mode 100644 index 0000000..4ef4dc4 --- /dev/null +++ b/Source/BusyRabbit/Public/UIFramework/MinimalWidget.h @@ -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; + +}; + + diff --git a/Source/BusyRabbit/Public/UIFramework/RootWidget.h b/Source/BusyRabbit/Public/UIFramework/RootWidget.h new file mode 100644 index 0000000..5303b71 --- /dev/null +++ b/Source/BusyRabbit/Public/UIFramework/RootWidget.h @@ -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 MainOverlay; +}; + + + diff --git a/Source/BusyRabbit/Public/UIFramework/UIController.h b/Source/BusyRabbit/Public/UIFramework/UIController.h new file mode 100644 index 0000000..a7f5c21 --- /dev/null +++ b/Source/BusyRabbit/Public/UIFramework/UIController.h @@ -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 Hud; + + UPROPERTY() + TObjectPtr PC; +}; diff --git a/Source/BusyRabbit/Public/UIFramework/UIFrameworkHud.h b/Source/BusyRabbit/Public/UIFramework/UIFrameworkHud.h new file mode 100644 index 0000000..bdfdd78 --- /dev/null +++ b/Source/BusyRabbit/Public/UIFramework/UIFrameworkHud.h @@ -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 RootWidgetClass; + + UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) + TMap> UIControllerClasses; + +protected: + UPROPERTY() + TObjectPtr UIManager; + + UPROPERTY() + TMap UIControllers; +}; + + + diff --git a/Source/BusyRabbit/Public/UIFramework/UIManager.h b/Source/BusyRabbit/Public/UIFramework/UIManager.h new file mode 100644 index 0000000..b0672e9 --- /dev/null +++ b/Source/BusyRabbit/Public/UIFramework/UIManager.h @@ -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 WidgetPanelStack; + + UPROPERTY() + TObjectPtr RootWidget; +}; diff --git a/Source/BusyRabbit/Public/UIFramework/WidgetPanel.h b/Source/BusyRabbit/Public/UIFramework/WidgetPanel.h new file mode 100644 index 0000000..9d87b48 --- /dev/null +++ b/Source/BusyRabbit/Public/UIFramework/WidgetPanel.h @@ -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: + +};