diff --git a/Content/Blueprint/Level/Actor/Role/BP_Fox.uasset b/Content/Blueprint/Level/Actor/Role/BP_Fox.uasset index e267e6d..5ca8e0c 100644 Binary files a/Content/Blueprint/Level/Actor/Role/BP_Fox.uasset and b/Content/Blueprint/Level/Actor/Role/BP_Fox.uasset differ diff --git a/Content/Blueprint/Level/Actor/Static/BP_Campsite.uasset b/Content/Blueprint/Level/Actor/Static/BP_Campsite.uasset index a855f54..dc64130 100644 Binary files a/Content/Blueprint/Level/Actor/Static/BP_Campsite.uasset and b/Content/Blueprint/Level/Actor/Static/BP_Campsite.uasset differ diff --git a/Content/Data/Level/LevelRoleBaseConfig.uasset b/Content/Data/Level/LevelRoleBaseConfig.uasset index dc4eb13..506ce60 100644 Binary files a/Content/Data/Level/LevelRoleBaseConfig.uasset and b/Content/Data/Level/LevelRoleBaseConfig.uasset differ diff --git a/Content/Resource/Texture/UI/RoleState/HealthBorder.uasset b/Content/Resource/Texture/UI/RoleState/HealthBorder.uasset new file mode 100644 index 0000000..b76faa1 Binary files /dev/null and b/Content/Resource/Texture/UI/RoleState/HealthBorder.uasset differ diff --git a/Content/Resource/Texture/UI/RoleState/HealthMask.uasset b/Content/Resource/Texture/UI/RoleState/HealthMask.uasset new file mode 100644 index 0000000..0bab6fb Binary files /dev/null and b/Content/Resource/Texture/UI/RoleState/HealthMask.uasset differ diff --git a/Content/Resource/Texture/UI/RoleState/Heart.uasset b/Content/Resource/Texture/UI/RoleState/Heart.uasset deleted file mode 100644 index e5090ae..0000000 Binary files a/Content/Resource/Texture/UI/RoleState/Heart.uasset and /dev/null differ diff --git a/Content/Resource/Texture/UI/RoleState/SatietyBorder.uasset b/Content/Resource/Texture/UI/RoleState/SatietyBorder.uasset new file mode 100644 index 0000000..b07018d Binary files /dev/null and b/Content/Resource/Texture/UI/RoleState/SatietyBorder.uasset differ diff --git a/Content/Resource/Texture/UI/RoleState/SatietyMask.uasset b/Content/Resource/Texture/UI/RoleState/SatietyMask.uasset new file mode 100644 index 0000000..f4cc6cd Binary files /dev/null and b/Content/Resource/Texture/UI/RoleState/SatietyMask.uasset differ diff --git a/Content/Resource/Texture/UI/RoleState/icon.uasset b/Content/Resource/Texture/UI/RoleState/icon.uasset deleted file mode 100644 index bf1c14b..0000000 Binary files a/Content/Resource/Texture/UI/RoleState/icon.uasset and /dev/null differ diff --git a/Content/UI/Level/StateBar/WBP_HealthBar.uasset b/Content/UI/Level/StateBar/WBP_HealthBar.uasset index b1a0378..1891134 100644 Binary files a/Content/UI/Level/StateBar/WBP_HealthBar.uasset and b/Content/UI/Level/StateBar/WBP_HealthBar.uasset differ diff --git a/Content/UI/Level/StateBar/WBP_SatietyBar.uasset b/Content/UI/Level/StateBar/WBP_SatietyBar.uasset index 4d41800..b1d654b 100644 Binary files a/Content/UI/Level/StateBar/WBP_SatietyBar.uasset 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 index 2e6e67c..70ba1d7 100644 Binary files a/Content/UI/Level/StateBar/WBP_StateBar.uasset and b/Content/UI/Level/StateBar/WBP_StateBar.uasset differ diff --git a/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyStateBar.cs b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyStateBar.cs index b860a1b..4c85839 100644 --- a/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyStateBar.cs +++ b/Script/ManagedBusyRabbit/UI/Level/StateBar/BusyStateBar.cs @@ -10,7 +10,10 @@ namespace UI.Level.StateBar; 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 UBusyWidgetSatietyBar? WBP_SatietyBar { get { return GetWidget("WBP_SatietyBar") as UBusyWidgetSatietyBar; } } + + protected List SatietyBars = new(); + protected List HealthBars = new(); protected UBusyRoleStateController? UIController; @@ -18,13 +21,26 @@ public class UBusyWidgetStateBar : UPW_MinimalWidget public override void Construct() { base.Construct(); - WBP_SatietyBar.SetSatietyConfig(100, 200); + + + for (int i = 0; i < 5; ++i) + { + if (GetWidget($"WBP_SatietyBar_{i}") is UBusyWidgetSatietyBar Bar) + { + SatietyBars.Add(Bar); + } + if (GetWidget("WBP_HealthBar") is UBusyWidgetHealthBar HpBar) + { + HealthBars.Add(HpBar); + } + } UIController = UUIFunctionLibrary.GetUIController(this, "RoleState") as UBusyRoleStateController; InitRoleAttribute(); UIController.OnAttributeChangeDelegate += OnAttributeChanged; + } public void InitRoleAttribute() @@ -34,7 +50,12 @@ public class UBusyWidgetStateBar : UPW_MinimalWidget float CurSatiety = UIController.GetControlledAttribute("Hunger"); float MaxSatiety = UIController.GetControlledAttribute("MaxHunger"); WBP_HealthBar.SetHpConfig(CurHealth, MaxHealth); - WBP_SatietyBar.SetSatietyConfig(CurSatiety, MaxSatiety); + + foreach (UBusyWidgetSatietyBar Bar in SatietyBars) + { + Bar.SetSatietyConfig(CurSatiety, MaxSatiety); + } + } public override void Destruct() @@ -43,13 +64,22 @@ public class UBusyWidgetStateBar : UPW_MinimalWidget UIController.OnAttributeChangeDelegate -= OnAttributeChanged; } + public void SetSatiety(float Satiety) + { + foreach(UBusyWidgetSatietyBar Bar in SatietyBars) + { + Bar.OnSatietyChanged(Satiety); + } + + } + [UFunction()] protected void OnAttributeChanged(FName AttributeName, float NewValue, float OldValue) { if (AttributeName == "Hunger") { - WBP_SatietyBar.OnSatietyChanged(NewValue); + SetSatiety(NewValue); } } } diff --git a/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp b/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp index 4bee203..9dbde18 100644 --- a/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/BusyPlayerRole.cpp @@ -2,6 +2,7 @@ #include "Camera/CameraComponent.h" #include "Data/BusyPawnConfig.h" #include "GameFramework/SpringArmComponent.h" +#include "Level/RoleTask/BusyTaskSubSystem.h" ABusyPlayerRole::ABusyPlayerRole() @@ -45,3 +46,51 @@ void ABusyPlayerRole::InitPawnAttributes(const struct FBusyPawnBaseConfig& Confi // } } +void ABusyPlayerRole::AddTask(UBusyRoleTaskBase* RoleTask) +{ + if (RoleTask) + { + RoleTasks.Enqueue(RoleTask); + } + ProcessTasks(); +} + +void ABusyPlayerRole::ProcessTasks() +{ + const auto PeekPtr = RoleTasks.Peek(); + if (PeekPtr == nullptr) + { + // 已经没有任务了,开启一个6s的回家定时器 + if (GoBackTimerHandle.IsValid()) + { + return; + } + GetWorldTimerManager().SetTimer(GoBackTimerHandle, [this]() + { + if (UBusyTaskSubSystem* SubSystem = UBusyTaskSubSystem::Get(this)) + { + AddTask(SubSystem->CreateGoBackTask()); + } + }, 6.0, false); + return; + } + GetWorldTimerManager().ClearTimer(GoBackTimerHandle); // 有任务的情况,清掉回家的定时器 + const TWeakObjectPtr& Task = *PeekPtr; + if (!Task.Get()) // Task无效,pop掉再指向一次 + { + RoleTasks.Pop(); + ProcessTasks(); + return; + } + if (Task->IsActive()) // 正在激活, 直接返回 + { + return; + } + Task->Activate(this, FOnBusyRoleTaskFinished::CreateLambda([this](bool bIsCancel) + { + RoleTasks.Pop(); + ProcessTasks(); + })); +} + + diff --git a/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp b/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp index 607d6fa..8cb5d0e 100644 --- a/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp +++ b/Source/BusyRabbit/Private/Level/Actor/Components/BusyPawnMovement.cpp @@ -109,6 +109,7 @@ void UBusyPawnMovement::MoveTick(const float DeltaTime) if (NewLocation.Equals(CurrentLocation)) { BusyMoveState = EBusyMoveState::None; + OnMoveFinished.Broadcast(); } else { diff --git a/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp b/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp index c19ff9a..2586f54 100644 --- a/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp +++ b/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp @@ -4,6 +4,7 @@ #include "EnhancedInput/Public/EnhancedInputSubsystems.h" #include "Level/LevelPlayerState.h" #include "EnhancedInput/Public/EnhancedInputComponent.h" +#include "Level/RoleTask/BusyTaskSubSystem.h" inline static void BindEnhancedInputAction(UEnhancedInputComponent* EnhancedInput, const UInputAction* Action, UObject* Target, const FName& Callback) @@ -181,6 +182,20 @@ void ALevelPlayerController::OnSwitchRole(const FInputActionValue& Value) } } +void ALevelPlayerController::OnMove(const FInputActionValue& Value) +{ + if (ABusyPlayerRole* ControlledRole = GetControlledRole()) + { + if (UBusyTaskSubSystem* SubSystem = UBusyTaskSubSystem::Get(this)) + { + if (FVector2D CursorPosition; GetCursorPosition(CursorPosition)) + { + ControlledRole->AddTask(SubSystem->CreateMoveTask(CursorPosition)); + } + } + } +} + void ALevelPlayerController::OnRoleSkillTriggered(FGameplayTag GameplayTag) { AActor* ControlledRole = GetControlledRole(); diff --git a/Source/BusyRabbit/Private/Level/RoleTask/BusyRoleMoveTask.cpp b/Source/BusyRabbit/Private/Level/RoleTask/BusyRoleMoveTask.cpp new file mode 100644 index 0000000..be18b5a --- /dev/null +++ b/Source/BusyRabbit/Private/Level/RoleTask/BusyRoleMoveTask.cpp @@ -0,0 +1,29 @@ +#include "Level/RoleTask/BusyRoleMoveTask.h" +#include "Level/Actor/BusyPlayerRole.h" + +void UBusyRoleMoveTask::Activate(ABusyPlayerRole* Owner, const FOnBusyRoleTaskFinished& Delegate) +{ + UBusyRoleTaskBase::Activate(Owner, Delegate); + Owner->MovementComponent->MoveTo(TargetLocation); + Owner->MovementComponent->OnMoveFinished.AddDynamic(this, &ThisClass::OnMoveFinished); +} + +void UBusyRoleMoveTask::Cancel() +{ + UBusyRoleTaskBase::Cancel(); +} + +void UBusyRoleMoveTask::SetTargetLocation(const FVector2D& NewLocation) +{ + TargetLocation = NewLocation; +} + +void UBusyRoleMoveTask::OnMoveFinished() +{ + if (OnFinishedDelegate.IsBound()) + { + OnFinishedDelegate.Execute(false); + } + TaskOwner->MovementComponent->OnMoveFinished.RemoveDynamic(this, &ThisClass::OnMoveFinished); + bIsActive = false; +} diff --git a/Source/BusyRabbit/Private/Level/RoleTask/BusyRolePickTask.cpp b/Source/BusyRabbit/Private/Level/RoleTask/BusyRolePickTask.cpp new file mode 100644 index 0000000..d572435 --- /dev/null +++ b/Source/BusyRabbit/Private/Level/RoleTask/BusyRolePickTask.cpp @@ -0,0 +1 @@ +#include "Level/RoleTask/BusyRolePickTask.h" diff --git a/Source/BusyRabbit/Private/Level/RoleTask/BusyTaskSubSystem.cpp b/Source/BusyRabbit/Private/Level/RoleTask/BusyTaskSubSystem.cpp new file mode 100644 index 0000000..954d7e9 --- /dev/null +++ b/Source/BusyRabbit/Private/Level/RoleTask/BusyTaskSubSystem.cpp @@ -0,0 +1,57 @@ +#include "Level/RoleTask/BusyTaskSubSystem.h" +#include "Level/RoleTask/BusyRoleMoveTask.h" + +bool UBusyRoleTaskBase::IsActive() const +{ + return bIsActive; +} + +void UBusyRoleTaskBase::Activate(ABusyPlayerRole* Owner, const FOnBusyRoleTaskFinished& Delegate) +{ + TaskOwner = Owner; + bIsActive = true; + OnFinishedDelegate = Delegate; +} + +void UBusyRoleTaskBase::Cancel() +{ + bIsActive = false; + if (OnFinishedDelegate.IsBound()) + { + OnFinishedDelegate.Execute(true); + } +} + +UBusyTaskSubSystem* UBusyTaskSubSystem::Get(const UObject* Object) +{ + const UWorld* World = Object->GetWorld(); + return World->GetSubsystem(); +} + +UBusyRoleTaskBase* UBusyTaskSubSystem::CreatePickTask(const ABusyStaticResource* Resource) +{ + + return nullptr; +} + +UBusyRoleTaskBase* UBusyTaskSubSystem::CreateMoveTask(const FVector2D& TargetPosition) +{ + UBusyRoleMoveTask* Task = NewObject(); + Task->SetTargetLocation(TargetPosition); + return Task; +} + +UBusyRoleTaskBase* UBusyTaskSubSystem::CreateGoBackTask() +{ + return nullptr; +} + +UBusyRoleTaskBase* UBusyTaskSubSystem::CreateBuildTask(const FName& BuildingID, const FVector2D& TargetPosition) +{ + return nullptr; +} + +UBusyRoleTaskBase* UBusyTaskSubSystem::CreateDismantleTask(const FName& BuildingID, const FVector2D& TargetPosition) +{ + return nullptr; +} diff --git a/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h b/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h index 1e2495b..3737abc 100644 --- a/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h +++ b/Source/BusyRabbit/Public/Level/Actor/BusyPlayerRole.h @@ -11,6 +11,8 @@ GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \ GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName) +class UBusyRoleTaskBase; + UCLASS(Blueprintable, BlueprintType) class UBusyPlayerRoleAttributeSet: public UBusyPawnAttributeSet { @@ -45,11 +47,18 @@ public: virtual void BeginPlay() override; - virtual void InitPawnAttributes(const struct FBusyPawnBaseConfig& Config)override; virtual void OnMoveDirectionChanged_Implementation(const FVector2D& InDirection) override {} +public: + UFUNCTION(BlueprintCallable) + void AddTask(UBusyRoleTaskBase* RoleTask); + +protected: + void ProcessTasks(); + + protected: /*--------------------相机相关--------------------------*/ UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) @@ -57,4 +66,9 @@ protected: UPROPERTY(EditDefaultsOnly, BlueprintReadWrite) TObjectPtr CameraComponent; + +protected: + FTimerHandle GoBackTimerHandle; + TQueue> RoleTasks; + }; diff --git a/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h b/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h index 779e2b2..aed3b34 100644 --- a/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h +++ b/Source/BusyRabbit/Public/Level/Actor/Components/BusyPawnMovement.h @@ -34,6 +34,7 @@ enum class EBusyMoveState: uint8 }; +DECLARE_DYNAMIC_MULTICAST_DELEGATE(FBusyMoveFinishedSignature); DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FBusyMoveDirectionChanged, FVector2D, Direction); @@ -106,6 +107,9 @@ public: public: UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement") FBusyMoveDirectionChanged MoveDirectionChangedDelegate; + + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Movement") + FBusyMoveFinishedSignature OnMoveFinished; protected: UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Movement") diff --git a/Source/BusyRabbit/Public/Level/LevelPlayerController.h b/Source/BusyRabbit/Public/Level/LevelPlayerController.h index da43fe0..5ada1fb 100644 --- a/Source/BusyRabbit/Public/Level/LevelPlayerController.h +++ b/Source/BusyRabbit/Public/Level/LevelPlayerController.h @@ -97,6 +97,9 @@ public: UFUNCTION() void OnSwitchRole(const FInputActionValue& Value); + UFUNCTION() + void OnMove(const FInputActionValue& Value); + UFUNCTION() void OnRoleSkillTriggered(FGameplayTag GameplayTag); diff --git a/Source/BusyRabbit/Public/Level/RoleTask/BusyRoleMoveTask.h b/Source/BusyRabbit/Public/Level/RoleTask/BusyRoleMoveTask.h new file mode 100644 index 0000000..0274d02 --- /dev/null +++ b/Source/BusyRabbit/Public/Level/RoleTask/BusyRoleMoveTask.h @@ -0,0 +1,22 @@ +#pragma once + +#include "Level/RoleTask/BusyTaskSubSystem.h" +#include "BusyRoleMoveTask.generated.h" + +UCLASS() +class UBusyRoleMoveTask : public UBusyRoleTaskBase +{ + GENERATED_BODY() +public: + virtual void Activate(ABusyPlayerRole* Owner, const FOnBusyRoleTaskFinished& Delegate) override; + virtual void Cancel() override; +public: + void SetTargetLocation(const FVector2D& NewLocation); + +private: + UFUNCTION() + void OnMoveFinished(); + +private: + FVector2D TargetLocation = FVector2D(); +}; diff --git a/Source/BusyRabbit/Public/Level/RoleTask/BusyRolePickTask.h b/Source/BusyRabbit/Public/Level/RoleTask/BusyRolePickTask.h new file mode 100644 index 0000000..87bffc5 --- /dev/null +++ b/Source/BusyRabbit/Public/Level/RoleTask/BusyRolePickTask.h @@ -0,0 +1,7 @@ +#pragma once + +class BusyRolePickTask +{ +public: + +}; diff --git a/Source/BusyRabbit/Public/Level/RoleTask/BusyTaskSubSystem.h b/Source/BusyRabbit/Public/Level/RoleTask/BusyTaskSubSystem.h new file mode 100644 index 0000000..a890de8 --- /dev/null +++ b/Source/BusyRabbit/Public/Level/RoleTask/BusyTaskSubSystem.h @@ -0,0 +1,69 @@ +#pragma once + +#include "Level/Actor/BusyPlayerRole.h" +#include "BusyTaskSubSystem.generated.h" + +class ABusyStaticResource; + +DECLARE_DELEGATE_OneParam(FOnBusyRoleTaskFinished, bool); + + +enum EBusyRoleTaskType +{ + Unknown = 0, + MoveTask = 1, + GobackTask = 2, + PickTask = 3, + BuildTask = 4, + DismantleTask = 5, +}; + + +UCLASS() +class UBusyRoleTaskBase : public UObject +{ + GENERATED_BODY() + +public: + bool IsActive() const; + + virtual void Activate(ABusyPlayerRole* Owner, const FOnBusyRoleTaskFinished &Delegate); + virtual void Cancel(); +protected: + bool bIsActive; + EBusyRoleTaskType TaskType; + TWeakObjectPtr TaskOwner; + FOnBusyRoleTaskFinished OnFinishedDelegate; +}; + + + + + + +UCLASS(BlueprintType) +class UBusyTaskSubSystem : public UWorldSubsystem +{ + GENERATED_BODY() +public: + UFUNCTION(BlueprintCallable) + static UBusyTaskSubSystem* Get(const UObject* Object); +public: + UFUNCTION(BlueprintCallable) + UBusyRoleTaskBase* CreatePickTask(const ABusyStaticResource* Resource); + + UFUNCTION(BlueprintCallable) + UBusyRoleTaskBase* CreateMoveTask(const FVector2D& TargetPosition); + + UFUNCTION(BlueprintCallable) + UBusyRoleTaskBase* CreateGoBackTask(); + + UFUNCTION(BlueprintCallable) + UBusyRoleTaskBase* CreateBuildTask(const FName& BuildingID, const FVector2D& TargetPosition); + + UFUNCTION(BlueprintCallable) + UBusyRoleTaskBase* CreateDismantleTask(const FName& BuildingID, const FVector2D& TargetPosition); + + + +};