@ -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();
 | 
			
		||||
	}));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -109,6 +109,7 @@ void UBusyPawnMovement::MoveTick(const float DeltaTime)
 | 
			
		||||
	if (NewLocation.Equals(CurrentLocation))
 | 
			
		||||
	{
 | 
			
		||||
		BusyMoveState = EBusyMoveState::None;
 | 
			
		||||
		OnMoveFinished.Broadcast();
 | 
			
		||||
	}
 | 
			
		||||
	else
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -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();
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1 @@
 | 
			
		||||
#include "Level/RoleTask/BusyRolePickTask.h"
 | 
			
		||||
@ -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;
 | 
			
		||||
}
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
@ -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")
 | 
			
		||||
 | 
			
		||||
@ -97,6 +97,9 @@ public:
 | 
			
		||||
	UFUNCTION()
 | 
			
		||||
	void OnSwitchRole(const FInputActionValue& Value);
 | 
			
		||||
 | 
			
		||||
	UFUNCTION()
 | 
			
		||||
	void OnMove(const FInputActionValue& Value);
 | 
			
		||||
	
 | 
			
		||||
	UFUNCTION()
 | 
			
		||||
	void OnRoleSkillTriggered(FGameplayTag GameplayTag);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								Source/BusyRabbit/Public/Level/RoleTask/BusyRoleMoveTask.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								Source/BusyRabbit/Public/Level/RoleTask/BusyRoleMoveTask.h
									
									
									
									
									
										Normal 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();
 | 
			
		||||
};
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
class BusyRolePickTask
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										69
									
								
								Source/BusyRabbit/Public/Level/RoleTask/BusyTaskSubSystem.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								Source/BusyRabbit/Public/Level/RoleTask/BusyTaskSubSystem.h
									
									
									
									
									
										Normal 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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user