Files
video-record-ue-poc/Source/AudioVideoRecord/Variant_Shooter/ShooterPlayerController.cpp

143 lines
3.8 KiB
C++
Raw Normal View History

2026-03-11 11:25:15 +05:30
// Copyright Epic Games, Inc. All Rights Reserved.
#include "Variant_Shooter/ShooterPlayerController.h"
#include "EnhancedInputSubsystems.h"
#include "Engine/LocalPlayer.h"
#include "InputMappingContext.h"
#include "Kismet/GameplayStatics.h"
#include "GameFramework/PlayerStart.h"
#include "ShooterCharacter.h"
#include "ShooterBulletCounterUI.h"
#include "AudioVideoRecord.h"
#include "Widgets/Input/SVirtualJoystick.h"
void AShooterPlayerController::BeginPlay()
{
Super::BeginPlay();
// only spawn touch controls on local player controllers
if (IsLocalPlayerController())
{
if (SVirtualJoystick::ShouldDisplayTouchInterface())
{
// spawn the mobile controls widget
MobileControlsWidget = CreateWidget<UUserWidget>(this, MobileControlsWidgetClass);
if (MobileControlsWidget)
{
// add the controls to the player screen
MobileControlsWidget->AddToPlayerScreen(0);
} else {
UE_LOG(LogAudioVideoRecord, Error, TEXT("Could not spawn mobile controls widget."));
}
}
// create the bullet counter widget and add it to the screen
BulletCounterUI = CreateWidget<UShooterBulletCounterUI>(this, BulletCounterUIClass);
if (BulletCounterUI)
{
BulletCounterUI->AddToPlayerScreen(0);
} else {
UE_LOG(LogAudioVideoRecord, Error, TEXT("Could not spawn bullet counter widget."));
}
}
}
void AShooterPlayerController::SetupInputComponent()
{
// only add IMCs for local player controllers
if (IsLocalPlayerController())
{
// add the input mapping contexts
if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(GetLocalPlayer()))
{
for (UInputMappingContext* CurrentContext : DefaultMappingContexts)
{
Subsystem->AddMappingContext(CurrentContext, 0);
}
// only add these IMCs if we're not using mobile touch input
if (!SVirtualJoystick::ShouldDisplayTouchInterface())
{
for (UInputMappingContext* CurrentContext : MobileExcludedMappingContexts)
{
Subsystem->AddMappingContext(CurrentContext, 0);
}
}
}
}
}
void AShooterPlayerController::OnPossess(APawn* InPawn)
{
Super::OnPossess(InPawn);
// subscribe to the pawn's OnDestroyed delegate
InPawn->OnDestroyed.AddDynamic(this, &AShooterPlayerController::OnPawnDestroyed);
// is this a shooter character?
if (AShooterCharacter* ShooterCharacter = Cast<AShooterCharacter>(InPawn))
{
// add the player tag
ShooterCharacter->Tags.Add(PlayerPawnTag);
// subscribe to the pawn's delegates
ShooterCharacter->OnBulletCountUpdated.AddDynamic(this, &AShooterPlayerController::OnBulletCountUpdated);
ShooterCharacter->OnDamaged.AddDynamic(this, &AShooterPlayerController::OnPawnDamaged);
// force update the life bar
ShooterCharacter->OnDamaged.Broadcast(1.0f);
}
}
void AShooterPlayerController::OnPawnDestroyed(AActor* DestroyedActor)
{
// reset the bullet counter HUD
BulletCounterUI->BP_UpdateBulletCounter(0, 0);
// find the player start
TArray<AActor*> ActorList;
UGameplayStatics::GetAllActorsOfClass(GetWorld(), APlayerStart::StaticClass(), ActorList);
if (ActorList.Num() > 0)
{
// select a random player start
AActor* RandomPlayerStart = ActorList[FMath::RandRange(0, ActorList.Num() - 1)];
// spawn a character at the player start
const FTransform SpawnTransform = RandomPlayerStart->GetActorTransform();
if (AShooterCharacter* RespawnedCharacter = GetWorld()->SpawnActor<AShooterCharacter>(CharacterClass, SpawnTransform))
{
// possess the character
Possess(RespawnedCharacter);
}
}
}
void AShooterPlayerController::OnBulletCountUpdated(int32 MagazineSize, int32 Bullets)
{
// update the UI
if (BulletCounterUI)
{
BulletCounterUI->BP_UpdateBulletCounter(MagazineSize, Bullets);
}
}
void AShooterPlayerController::OnPawnDamaged(float LifePercent)
{
if (IsValid(BulletCounterUI))
{
BulletCounterUI->BP_Damaged(LifePercent);
}
}