Add Player Character
This commit is contained in:
parent
26e875e47e
commit
87b2102733
Binary file not shown.
|
@ -0,0 +1,43 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "NakatomiCharacter.h"
|
||||||
|
|
||||||
|
// Sets default values
|
||||||
|
ANakatomiCharacter::ANakatomiCharacter()
|
||||||
|
{
|
||||||
|
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||||
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
|
|
||||||
|
HealthComponent = CreateDefaultSubobject<UHealthComponent>(TEXT("Health Component"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the game starts or when spawned
|
||||||
|
void ANakatomiCharacter::BeginPlay()
|
||||||
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called every frame
|
||||||
|
void ANakatomiCharacter::Tick(float DeltaTime)
|
||||||
|
{
|
||||||
|
Super::Tick(DeltaTime);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called to bind functionality to input
|
||||||
|
void ANakatomiCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
||||||
|
{
|
||||||
|
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
UHealthComponent* ANakatomiCharacter::GetHealthComponent()
|
||||||
|
{
|
||||||
|
return HealthComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ANakatomiCharacter::SetHealthComponent(UHealthComponent* component)
|
||||||
|
{
|
||||||
|
HealthComponent = component;
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameFramework/Character.h"
|
||||||
|
#include "HealthComponent.h"
|
||||||
|
#include "NakatomiCharacter.generated.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class NAKATOMI_API ANakatomiCharacter : public ACharacter
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
UPROPERTY(VisibleDefaultsOnly)
|
||||||
|
UHealthComponent* HealthComponent = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Sets default values for this character's properties
|
||||||
|
ANakatomiCharacter();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Called when the game starts or when spawned
|
||||||
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Called every frame
|
||||||
|
virtual void Tick(float DeltaTime) override;
|
||||||
|
|
||||||
|
// Called to bind functionality to input
|
||||||
|
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
||||||
|
|
||||||
|
UHealthComponent* GetHealthComponent();
|
||||||
|
|
||||||
|
void SetHealthComponent(UHealthComponent* healthComponent);
|
||||||
|
};
|
|
@ -0,0 +1,201 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
|
||||||
|
#include "PlayerCharacter.h"
|
||||||
|
// You can remove these, this is just to get intellisense to work
|
||||||
|
#include "InputTriggers.h"
|
||||||
|
#include "EnhancedInputComponent.h"
|
||||||
|
#include "EnhancedInputSubsystems.h"
|
||||||
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
|
#include "InputMappingContext.h"
|
||||||
|
|
||||||
|
#define COLLISION_WEAPON ECC_GameTraceChannel1
|
||||||
|
|
||||||
|
// Sets default values
|
||||||
|
APlayerCharacter::APlayerCharacter()
|
||||||
|
{
|
||||||
|
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
||||||
|
PrimaryActorTick.bCanEverTick = true;
|
||||||
|
PrimaryActorTick.SetTickFunctionEnable(true);
|
||||||
|
PrimaryActorTick.bStartWithTickEnabled = true;
|
||||||
|
|
||||||
|
//bUseControllerRotationPitch = true;
|
||||||
|
//bUseControllerRotationYaw = true;
|
||||||
|
//bUseControllerRotationRoll = false;
|
||||||
|
|
||||||
|
// Setup the camera boom
|
||||||
|
CameraBoom = CreateDefaultSubobject<USpringArmComponent>(TEXT("CameraBoom"));
|
||||||
|
CameraBoom->SetupAttachment(RootComponent);
|
||||||
|
CameraBoom->bDoCollisionTest = true;
|
||||||
|
CameraBoom->bUsePawnControlRotation = true;
|
||||||
|
CameraBoom->TargetArmLength = 500.0f;
|
||||||
|
CameraBoom->bEnableCameraLag = true;
|
||||||
|
CameraBoom->CameraLagSpeed = 10.0f;
|
||||||
|
CameraBoom->SocketOffset = { 0.0f, 0.0f, 220.0f };
|
||||||
|
|
||||||
|
// Setup the camera component
|
||||||
|
CameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("CameraComponent"));
|
||||||
|
CameraComponent->SetupAttachment(CameraBoom, USpringArmComponent::SocketName);
|
||||||
|
CameraComponent->bUsePawnControlRotation = false;
|
||||||
|
CameraComponent->SetRelativeRotation({ -10.0f,0.0f,0.0f });
|
||||||
|
|
||||||
|
// Setup the character movement
|
||||||
|
UCharacterMovementComponent* CharacterMovementComponent = GetCharacterMovement();
|
||||||
|
CharacterMovementComponent->AirControl = 1.0f;
|
||||||
|
CharacterMovementComponent->bOrientRotationToMovement = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called when the game starts or when spawned
|
||||||
|
void APlayerCharacter::BeginPlay()
|
||||||
|
{
|
||||||
|
Super::BeginPlay();
|
||||||
|
|
||||||
|
DefaultMovementSpeed = GetCharacterMovement()->MaxWalkSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called every frame
|
||||||
|
void APlayerCharacter::Tick(float DeltaTime)
|
||||||
|
{
|
||||||
|
Super::Tick(DeltaTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called to bind functionality to input
|
||||||
|
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
|
||||||
|
{
|
||||||
|
Super::SetupPlayerInputComponent(PlayerInputComponent);
|
||||||
|
|
||||||
|
if (APlayerController* PC = Cast<APlayerController>(GetController()))
|
||||||
|
{
|
||||||
|
if (UEnhancedInputLocalPlayerSubsystem* InputSystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PC->GetLocalPlayer()))
|
||||||
|
{
|
||||||
|
if (!InputMappingContext.IsNull())
|
||||||
|
{
|
||||||
|
InputSystem->AddMappingContext(InputMappingContext.LoadSynchronous(), MappingPriority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UEnhancedInputComponent* Input = Cast<UEnhancedInputComponent>(PlayerInputComponent))
|
||||||
|
{
|
||||||
|
if (MovementAction)
|
||||||
|
{
|
||||||
|
Input->BindAction(MovementAction, ETriggerEvent::Triggered, this, &APlayerCharacter::MovementCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (LookAction)
|
||||||
|
{
|
||||||
|
Input->BindAction(LookAction, ETriggerEvent::Triggered, this, &APlayerCharacter::LookCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (JumpAction)
|
||||||
|
{
|
||||||
|
Input->BindAction(JumpAction, ETriggerEvent::Triggered, this, &APlayerCharacter::JumpCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FireAction)
|
||||||
|
{
|
||||||
|
Input->BindAction(FireAction, ETriggerEvent::Started, this, &APlayerCharacter::FireCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (QuitAction)
|
||||||
|
{
|
||||||
|
Input->BindAction(QuitAction, ETriggerEvent::Started, this, &APlayerCharacter::QuitCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SprintAction)
|
||||||
|
{
|
||||||
|
Input->BindAction(SprintAction, ETriggerEvent::Started, this, &APlayerCharacter::SetSprintingCallback);
|
||||||
|
Input->BindAction(SprintAction, ETriggerEvent::Completed, this, &APlayerCharacter::SetWalkingCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::MovementCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
FVector2D vec2 = Instance.GetValue().Get<FVector2D>();
|
||||||
|
|
||||||
|
if (vec2.Size() != 0.0f)
|
||||||
|
{
|
||||||
|
AddMovementInput(GetActorForwardVector(), vec2.Y);
|
||||||
|
AddMovementInput(GetActorRightVector(), vec2.X);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::LookCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
FVector2D vec2 = Instance.GetValue().Get<FVector2D>();
|
||||||
|
|
||||||
|
if (vec2.Size() != 0.0f)
|
||||||
|
{
|
||||||
|
AddControllerYawInput(vec2.X * 45.0f * GetWorld()->GetDeltaSeconds());
|
||||||
|
AddControllerPitchInput(vec2.Y * 45.0f * GetWorld()->GetDeltaSeconds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::JumpCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
Jump();
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::FireCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
// TODO: Add extra gun fire logic
|
||||||
|
|
||||||
|
// Calculate hits from hitscan
|
||||||
|
TArray<FHitResult> Hits = TArray<FHitResult>();
|
||||||
|
CalculateHits(&Hits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::QuitCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
FGenericPlatformMisc::RequestExit(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::SetSprintingCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
GetCharacterMovement()->MaxWalkSpeed = DefaultMovementSpeed * SprintSpeedMultiplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::SetWalkingCallback(const FInputActionInstance& Instance)
|
||||||
|
{
|
||||||
|
GetCharacterMovement()->MaxWalkSpeed = DefaultMovementSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void APlayerCharacter::CalculateHits(TArray<FHitResult>* hits)
|
||||||
|
{
|
||||||
|
// Set up randomness
|
||||||
|
const int32 RandomSeed = FMath::Rand();
|
||||||
|
FRandomStream WeaponRandomStream(RandomSeed);
|
||||||
|
const float Spread = 1.0f; // TODO: Replace with a more sensible value later
|
||||||
|
const float Range = 50000.f; // TODO: Replace with a more sensible value later
|
||||||
|
|
||||||
|
// Calculate starting position and direction
|
||||||
|
FVector TraceStart;
|
||||||
|
FRotator PlayerRot;
|
||||||
|
GetController<APlayerController>()->GetPlayerViewPoint(TraceStart, PlayerRot);
|
||||||
|
TraceStart = GetRootComponent()->GetComponentLocation();
|
||||||
|
FVector AimDir = PlayerRot.Vector();
|
||||||
|
AimDir.Z = 0.0;
|
||||||
|
TraceStart = TraceStart + AimDir * ((GetInstigator()->GetActorLocation() - TraceStart) | AimDir);
|
||||||
|
|
||||||
|
// Calculate the hit results from the trace
|
||||||
|
TArray<FHitResult> HitResults;
|
||||||
|
|
||||||
|
/// Set up the collision query params, use the Weapon trace settings, Ignore the actor firing this trace
|
||||||
|
FCollisionQueryParams TraceParams(SCENE_QUERY_STAT(WeaponTrace), true, GetInstigator());
|
||||||
|
TraceParams.bReturnPhysicalMaterial = true;
|
||||||
|
|
||||||
|
/// Calculate the maximum distance the weapon can fire
|
||||||
|
FVector ShootDir = WeaponRandomStream.VRandCone(AimDir, FMath::DegreesToRadians(Spread), FMath::DegreesToRadians(Spread));
|
||||||
|
FVector MaxHitLoc = TraceStart + (ShootDir * Range);
|
||||||
|
|
||||||
|
GetWorld()->LineTraceMultiByChannel(HitResults, TraceStart, MaxHitLoc, COLLISION_WEAPON, TraceParams);
|
||||||
|
|
||||||
|
for (FHitResult Result : HitResults)
|
||||||
|
{
|
||||||
|
hits->Add(Result);
|
||||||
|
DrawDebugLine(GetWorld(), TraceStart, Result.ImpactPoint, FColor::Blue, true, 500, 0U, 0);
|
||||||
|
|
||||||
|
// TODO: Handle hits in a meaningful way
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,97 @@
|
||||||
|
// Fill out your copyright notice in the Description page of Project Settings.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Camera/CameraComponent.h"
|
||||||
|
#include "CoreMinimal.h"
|
||||||
|
#include "GameFramework/SpringArmComponent.h"
|
||||||
|
#include "InputActionValue.h"
|
||||||
|
#include "EnhancedInputComponent.h"
|
||||||
|
#include "NakatomiCharacter.h"
|
||||||
|
#include "PlayerCharacter.generated.h"
|
||||||
|
|
||||||
|
class UInputAction;
|
||||||
|
class UInputMappingContext;
|
||||||
|
//class UEnhancedInputComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
UCLASS()
|
||||||
|
class NAKATOMI_API APlayerCharacter : public ANakatomiCharacter
|
||||||
|
{
|
||||||
|
GENERATED_BODY()
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Sets default values for this character's properties
|
||||||
|
APlayerCharacter();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Called when the game starts or when spawned
|
||||||
|
virtual void BeginPlay() override;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Called every frame
|
||||||
|
virtual void Tick(float DeltaTime) override;
|
||||||
|
|
||||||
|
// Called to bind functionality to input
|
||||||
|
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
USpringArmComponent* CameraBoom = nullptr;
|
||||||
|
|
||||||
|
UPROPERTY()
|
||||||
|
UCameraComponent* CameraComponent = nullptr;
|
||||||
|
|
||||||
|
float DefaultMovementSpeed;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
float SprintSpeedMultiplier = 2.0f;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
UInputAction* MovementAction;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
UInputAction* LookAction;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
UInputAction* JumpAction;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
UInputAction* FireAction;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
UInputAction* QuitAction;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
UInputAction* SprintAction;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
TSoftObjectPtr<UInputMappingContext> InputMappingContext;
|
||||||
|
|
||||||
|
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite)
|
||||||
|
int MappingPriority = 0;
|
||||||
|
|
||||||
|
void MovementCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void LookCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void JumpCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void FireCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void QuitCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void SetSprintingCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void SetWalkingCallback(const FInputActionInstance& Instance);
|
||||||
|
|
||||||
|
void CalculateHits(TArray<FHitResult>* hits);
|
||||||
|
};
|
Loading…
Reference in New Issue