Protptype of a wave based, first person shooter game made in Unreal Engine 4
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
MechDefence/Private/MPlayerMech.cpp

188 lines
6.3 KiB

// Fill out your copyright notice in the Description page of Project Settings.
#include "MPlayerMech.h"
#include "DrawDebugHelpers.h"
#include "MCharacter.h"
#include "NavigationSystem.h"
#include "Camera/CameraComponent.h"
#include "Components/CapsuleComponent.h"
#include "Components/BoxComponent.h"
#include "Components/ArrowComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "MHealthComponent.h"
#include "Components/WidgetComponent.h"
#include "EnvironmentQuery/EnvQueryManager.h"
#include "EnvironmentQuery/EnvQueryTypes.h"
#include "Kismet/GameplayStatics.h"
#include "Misc/OutputDeviceDebug.h"
int32 AMPlayerMech::DebugMechDrawing = 0;
FAutoConsoleVariableRef CVAR_DebugMechDrawing(
TEXT("MDEF.DebugMechDrawing"),
AMPlayerMech::DebugMechDrawing,
TEXT("Draw debug visualizations for the player mech"),
ECVF_Cheat);
AMPlayerMech::AMPlayerMech()
{
PrimaryActorTick.bCanEverTick = true;
MeshComponent = CreateDefaultSubobject<USkeletalMeshComponent>("MeshComponent");
RootComponent = MeshComponent;
SpringArmComponent = CreateDefaultSubobject<USpringArmComponent>("SpringArmComponent");
SpringArmComponent->SetupAttachment(MeshComponent);
SpringArmComponent->TargetArmLength = 1500.f;
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
CameraComponent->SetupAttachment(SpringArmComponent);
CameraComponent->SetRelativeLocation(FVector(0.f, 0.f, BaseEyeHeight));
HealthComponent = CreateDefaultSubobject<UMHealthComponent>(TEXT("HealthComponent"));
StatusIndicatorWidget = CreateDefaultSubobject<UWidgetComponent>(TEXT("StatusIndicator"));
StatusIndicatorWidget->SetupAttachment(RootComponent);
PlayerDismountRadius = 500.f;
PlayerDismountGroundOffset = 100.f;
ResetZOffset = 200.f;
MountedPlayerCharacter = nullptr;
}
void AMPlayerMech::BeginPlay()
{
Super::BeginPlay();
GetWorldTimerManager().SetTimerForNextTick(this, &AMPlayerMech::SetupHealthIndicator);
}
void AMPlayerMech::SetupHealthIndicator()
{
UUserWidget* IndicatorWidget = StatusIndicatorWidget->GetWidget();
if(IndicatorWidget)
{
FObjectProperty* ObjProp = FindFProperty<FObjectProperty>(IndicatorWidget->GetClass(), TEXT("HealthComponent"));
if(ObjProp)
{
ObjProp->SetObjectPropertyValue_InContainer(IndicatorWidget, HealthComponent, 0);
}
const FString Command = FString::Printf(TEXT("SetupHealthChangeAnims"));
FOutputDeviceDebug DebugOutputDevice;
if(!IndicatorWidget->CallFunctionByNameWithArguments(*Command, DebugOutputDevice, IndicatorWidget, true))
{
UE_LOG(LogTemp, Log, TEXT("Failed to setup health change anims"));
}
}
}
void AMPlayerMech::MoveForward(float ScaleValue)
{
//AddMovementInput(GetActorForwardVector(), ScaleValue);
}
void AMPlayerMech::MoveRight(float ScaleValue)
{
//AddMovementInput(GetActorRightVector(), ScaleValue);
//AddControllerYawInput(ScaleValue);
}
void AMPlayerMech::RequestDismount()
{
FEnvQueryRequest DismountQueryRequest = FEnvQueryRequest(DismountEQS);
DismountQueryRequest.Execute(EEnvQueryRunMode::SingleResult, this, &AMPlayerMech::HandleDismountResponse);
}
void AMPlayerMech::RevertOrientation()
{
const FRotator CameraOrientation = CameraComponent->GetComponentRotation();
const FRotator NewRotation(0.f, CameraOrientation.Yaw, 0.f);
const FVector NewLocation = GetActorLocation() + FVector(0.f, 0.f, ResetZOffset);
SetActorLocationAndRotation(NewLocation, NewRotation, false, nullptr, ETeleportType::TeleportPhysics);
}
void AMPlayerMech::HandleDismountResponse(TSharedPtr<FEnvQueryResult> QueryResult)
{
if(QueryResult->IsSuccsessful())
{
FVector DismountLocation = QueryResult->GetItemAsLocation(0);
if(DebugMechDrawing > 0)
DrawDebugSphere(GetWorld(), DismountLocation, 50.f, 20, FColor::Green, false, 5.f, 0, 1.f);
if(MountedPlayerCharacter)
{
MountedPlayerCharacter->DetachFromActor(FDetachmentTransformRules::KeepWorldTransform);
MountedPlayerCharacter->SetActorHiddenInGame(false);
MountedPlayerCharacter->SetActorEnableCollision(true);
MountedPlayerCharacter->SetActorTickEnabled(true);
//DismountLocation.Z += PlayerDismountGroundOffset; // Add a bit of offset from the ground to avoid player falling from the ground when dismounting
MountedPlayerCharacter->SetActorLocationAndRotation(DismountLocation, FRotator(0.f, GetActorRotation().Yaw, 0.f), false, nullptr, ETeleportType::ResetPhysics);
APlayerController* PC = Cast<APlayerController>(GetController());
if(PC)
{
PC->Possess(Cast<APawn>(MountedPlayerCharacter));
}
MountedPlayerCharacter->SetMounted(false);
MountedPlayerCharacter->CheckIfInSafeZone();
MountedPlayerCharacter = nullptr;
if(MountSound)
UGameplayStatics::PlaySound2D(this, MountSound);
}
}
else
{
UE_LOG(LogTemp, Log, TEXT("Could not find suitable location to dismount"));
}
}
void AMPlayerMech::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AMPlayerMech::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &AMPlayerMech::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &AMPlayerMech::MoveRight);
//PlayerInputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
PlayerInputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
PlayerInputComponent->BindAction("Dismount", IE_Pressed, this, &AMPlayerMech::RequestDismount);
PlayerInputComponent->BindAction("ResetVehicle", IE_Pressed, this, &AMPlayerMech::RevertOrientation);
}
void AMPlayerMech::MountPlayerCharacter(AMCharacter* PlayerCharacter)
{
if(!PlayerCharacter)
return;
MountedPlayerCharacter = PlayerCharacter;
MountedPlayerCharacter->SetActorHiddenInGame(true);
MountedPlayerCharacter->SetActorEnableCollision(false);
MountedPlayerCharacter->SetActorTickEnabled(false);
PlayerCharacter->AttachToActor(this, FAttachmentTransformRules::SnapToTargetNotIncludingScale, PlayerAttachmentSocket);
if(MountSound)
UGameplayStatics::PlaySound2D(this, MountSound);
}
void AMPlayerMech::GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const
{
TagContainer = ActorTags;
}
UMeshComponent* AMPlayerMech::GetHoveredMeshComponent()
{
return MeshComponent;
}