Files
BusyRabbit/Source/BusyRabbit/Private/Level/LevelPlayerController.cpp
2025-10-13 11:57:19 +08:00

195 lines
5.3 KiB
C++

#include "Level/LevelPlayerController.h"
#include "Level/Actor/BusyPlayerRole.h"
#include "EnhancedInput/Public/EnhancedInputSubsystems.h"
#include "Level/LevelPlayerState.h"
#include "EnhancedInput/Public/EnhancedInputComponent.h"
inline static void BindEnhancedInputAction(UEnhancedInputComponent* EnhancedInput, const UInputAction* Action, UObject* Target, const FName& Callback)
{
if (Action)
{
EnhancedInput->BindAction(Action, ETriggerEvent::Triggered, Target, Callback);
}
}
ALevelPlayerController::ALevelPlayerController()
{
}
void ALevelPlayerController::BeginPlay()
{
Super::BeginPlay();
bShowMouseCursor = true;
FInputModeGameAndUI InputMode;
InputMode.SetHideCursorDuringCapture(false);
InputMode.SetLockMouseToViewportBehavior(EMouseLockMode::DoNotLock);
SetInputMode(InputMode);
if (RoamingCameraClass)
{
RoamingCameraActor = GetWorld()->SpawnActor<AActor>(RoamingCameraClass);
}
}
void ALevelPlayerController::SetupInputComponent()
{
Super::SetupInputComponent();
// 注册输入
if (!InputMapping || !InputComponent) return;
if (const auto Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
Subsystem->AddMappingContext(InputMapping, 0);
}
UEnhancedInputComponent* EnhancedInput = CastChecked<UEnhancedInputComponent>(InputComponent);
if (!EnhancedInput) return;
BindEnhancedInputAction(EnhancedInput, MoveAction, this, "OnMove");
BindEnhancedInputAction(EnhancedInput, CameraDetachAction, this, "OnCameraDetach");
BindEnhancedInputAction(EnhancedInput, PrimarySkillAction, this, "OnPrimarySkill");
BindEnhancedInputAction(EnhancedInput, UltimateSkillAction, this, "OnUltimateSkill");
BindEnhancedInputAction(EnhancedInput, SwitchRoleAction, this, "OnSwitchRole");
}
void ALevelPlayerController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!bCameraDetached || !RoamingCameraActor) return;
AActor *ControlledRole = GetControlledRole();
const IBusyMovable *Movable = Cast<IBusyMovable>(GetControlledRole());
if (!Movable) return;
if (float CursorX, CursorY; GetMousePosition(CursorX, CursorY))
{
// 获取视口大小
int32 ViewportSizeX, ViewportSizeY;
GetViewportSize(ViewportSizeX, ViewportSizeY);
// 计算屏幕中心
const FVector2D ScreenCenter(ViewportSizeX / 2.0f, ViewportSizeY / 2.0f);
// 获取漫游相机位置
const FVector CurrentLocation = RoamingCameraActor->GetActorLocation();
// 计算方向向量
FVector Direction(CursorX - ScreenCenter.X, CursorY - ScreenCenter.Y, 0);
// 归一化
Direction.Normalize();
const float MoveSpeed = Movable->Execute_GetSpeed(ControlledRole);
const FVector MoveDistance = Direction * DeltaTime * MoveSpeed * RoamingSpeedFactor;
// 更新漫游相机位置
RoamingCameraActor->SetActorLocation(CurrentLocation + MoveDistance);
}
}
bool ALevelPlayerController::GetCursorPosition(FVector2D& Position) const
{
if (float CursorX, CursorY; GetMousePosition(CursorX, CursorY))
{
FVector WorldLocation, WorldDirection;
if (DeprojectMousePositionToWorld(WorldLocation, WorldDirection))
{
Position.Set(WorldLocation.X, WorldLocation.Y);
return true;
}
}
return false;
}
void ALevelPlayerController::GetCursorHitResult(TArray<AActor*>& Results) const
{
}
ABusyPlayerRole* ALevelPlayerController::GetControlledRole() const
{
if (const ALevelPlayerState* PS = GetPlayerState<ALevelPlayerState>())
{
return PS->GetControlledRole();
}
return nullptr;
}
void ALevelPlayerController::SwitchControlledRole(ABusyPlayerRole* Target)
{
this->Possess(Target);
}
void ALevelPlayerController::OnMove(const FInputActionValue& Value) const
{
AActor* ControlledRole = GetControlledRole();
if (!ControlledRole) return;
IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole);
if (!Controllable) return;
if (FVector2D Position; GetCursorPosition(Position))
{
Controllable->Execute_OnMove(ControlledRole, Position);
}
}
void ALevelPlayerController::OnPrimarySkill(const FInputActionValue& Value) const
{
AActor* ControlledRole = GetControlledRole();
if (!ControlledRole) return;
if (IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole))
{
Controllable->Execute_OnPrimarySkill(ControlledRole);
}
}
void ALevelPlayerController::OnUltimateSkill(const FInputActionValue& Value) const
{
AActor* ControlledRole = GetControlledRole();
if (!ControlledRole) return;
if (IBusyControllable *Controllable = Cast<IBusyControllable>(ControlledRole))
{
Controllable->Execute_OnUltimateSkill(ControlledRole);
}
}
void ALevelPlayerController::OnCameraDetach(const FInputActionValue& Value)
{
if (!RoamingCameraActor) return;
AActor* ControlledRole = GetControlledRole();
if (!ControlledRole) return;
const FVector RoleLocation = ControlledRole->GetActorLocation();
RoamingCameraActor->SetActorLocation(RoleLocation);
if (Value.GetMagnitude() > 0)
{
bCameraDetached = true;
SetViewTarget(RoamingCameraActor);
}
else
{
bCameraDetached = false;
SetViewTarget(ControlledRole);
}
}
void ALevelPlayerController::OnSwitchRole(const FInputActionValue& Value)
{
const int32 Index = static_cast<int32>(Value.GetMagnitude() - 1);
if (ALevelPlayerState* PS = GetPlayerState<ALevelPlayerState>())
{
ABusyPlayerRole* ControlledRole = PS->SwitchControlledRole(Index);
SwitchControlledRole(ControlledRole);
}
}