重构旧的采集系统和掉落系统 #3

Task和Ability系统初步接入,Task系统实现移动
This commit is contained in:
2025-11-02 15:51:28 +08:00
parent 39b100acff
commit 893a0743dd
25 changed files with 306 additions and 5 deletions

View File

@ -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<UBusyWidgetSatietyBar> SatietyBars = new();
protected List<UBusyWidgetHealthBar> 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);
}
}
}

View File

@ -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<UBusyRoleTaskBase>& 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();
}));
}

View File

@ -109,6 +109,7 @@ void UBusyPawnMovement::MoveTick(const float DeltaTime)
if (NewLocation.Equals(CurrentLocation))
{
BusyMoveState = EBusyMoveState::None;
OnMoveFinished.Broadcast();
}
else
{

View File

@ -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();

View File

@ -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;
}

View File

@ -0,0 +1 @@
#include "Level/RoleTask/BusyRolePickTask.h"

View File

@ -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<UBusyTaskSubSystem>();
}
UBusyRoleTaskBase* UBusyTaskSubSystem::CreatePickTask(const ABusyStaticResource* Resource)
{
return nullptr;
}
UBusyRoleTaskBase* UBusyTaskSubSystem::CreateMoveTask(const FVector2D& TargetPosition)
{
UBusyRoleMoveTask* Task = NewObject<UBusyRoleMoveTask>();
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;
}

View File

@ -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<class UCameraComponent> CameraComponent;
protected:
FTimerHandle GoBackTimerHandle;
TQueue<TWeakObjectPtr<UBusyRoleTaskBase>> RoleTasks;
};

View File

@ -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")

View File

@ -97,6 +97,9 @@ public:
UFUNCTION()
void OnSwitchRole(const FInputActionValue& Value);
UFUNCTION()
void OnMove(const FInputActionValue& Value);
UFUNCTION()
void OnRoleSkillTriggered(FGameplayTag GameplayTag);

View File

@ -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();
};

View File

@ -0,0 +1,7 @@
#pragma once
class BusyRolePickTask
{
public:
};

View File

@ -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<ABusyPlayerRole> 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);
};