Created
November 26, 2016 18:35
-
-
Save anonymous/b8678bd8edcafe863ae22fba0a8eabef to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//==============================================================================// | |
// | |
// Purpose: Player object | |
// | |
//=============================================================================// | |
#include "Portfolio.h" | |
#include "PortChar.h" | |
// Sets default values | |
APortChar::APortChar() | |
{ | |
// 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; | |
//initiate everything to false | |
isMovingForwardOrBack = false; | |
isMovingLeftOrRight = false; | |
isMovingForward = false; | |
World = GetWorld();//set up world variable | |
bCanStep = true; //initialize the variable so the timer can start. Timer never runs if this is false or NULL | |
WalkSpeed = 300; | |
CrouchSpeed = 150; | |
SprintSpeed = 600; //default sprint speed | |
GetCharacterMovement()->MaxWalkSpeed = WalkSpeed; | |
GetCapsuleComponent()->InitCapsuleSize(40.0f, 85.0f); | |
GetCharacterMovement()->NavAgentProps.bCanCrouch = true; | |
DecBEH = BaseEyeHeight; | |
DecCapsHeight = GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(); | |
} | |
// Called when the game starts or when spawned | |
void APortChar::BeginPlay() | |
{ | |
Super::BeginPlay(); | |
stepRate = WalkRate; | |
//assign PlayerCamera for shake to player 0 | |
PlayerCamera = UGameplayStatics::GetPlayerCameraManager(this, 0); | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: Detects whether the player is moving, runs the footsteps timer and sets up changing ground types | |
//----------------------------------------------------------------------------- | |
void APortChar::Tick(float DeltaTime) | |
{ | |
Super::Tick(DeltaTime); | |
if (Controller) | |
{ | |
CrouchImpl(DeltaTime); | |
} | |
if (isMovingForwardOrBack == true || isMovingLeftOrRight == true) | |
{ | |
isMoving = true; | |
} | |
else if (isMovingForwardOrBack == false && isMovingLeftOrRight == false) | |
{ | |
isMoving = false; | |
} | |
PlayFootsteps(); | |
//ground type for footsteps sound | |
FHitResult RV_DownHit; //the hit that detects what the player is standing on | |
//the hit that detects what the player is looking at | |
///////////////////////////////////////////////////// | |
////Downward Hit | |
//////////////////////////////////////////////////// | |
RV_TraceParams = FCollisionQueryParams(FName(TEXT("RV_Trace")), true, this); //set up trace params for the line tracing | |
RV_TraceParams.bReturnPhysicalMaterial = true; //makes it so we can detect what physical material the hit has | |
RV_TraceParams.bTraceComplex = true; | |
RV_TraceParams.bTraceAsyncScene = true; | |
//sets up the line trace. Extends a line from the root component down 95 units, just a little below the bottom of the capsule. | |
GetWorld()->LineTraceSingleByChannel(RV_DownHit, GetActorLocation(), GetActorLocation() + GetActorUpVector() * -95, ECC_Pawn, RV_TraceParams); | |
if (RV_DownHit.PhysMaterial == StoneMat)//if the material the player is standing on is stone | |
{ | |
StepType = 0; //set the steptype to stone | |
} | |
else if (RV_DownHit.PhysMaterial == SnowMat) //if the material is snow | |
{ | |
StepType = 1; //set the steptype to snow | |
} | |
else if (RV_DownHit.PhysMaterial == GrassMat) | |
{ | |
StepType = 2; //set the steptype to grass | |
} | |
else if (RV_DownHit.PhysMaterial == TileMat) | |
{ | |
StepType = 3; //set the steptype to tile | |
} | |
///////////////////////////////////////////////////// | |
////Forward Hit | |
//////////////////////////////////////////////////// | |
RV_ForwardParams = FCollisionQueryParams(FName(TEXT("RV_ForwardTrace")), true, this); //sets up the parameters for forward trace | |
RV_TraceParams.bReturnPhysicalMaterial = true; | |
RV_TraceParams.bTraceComplex = true; | |
RV_TraceParams.bTraceAsyncScene = true; | |
//sets up the line trace. Extends line from the root component forward 95 units | |
GetWorld()->LineTraceSingleByChannel(RV_ForwardHit, GetActorLocation(), GetActorLocation() + GetActorForwardVector() * 125, ECC_Pawn, RV_ForwardParams); | |
} | |
// Called to bind functionality to input | |
void APortChar::SetupPlayerInputComponent(class UInputComponent* InputComponent) | |
{ | |
Super::SetupPlayerInputComponent(InputComponent); | |
//set up movement bindings | |
InputComponent->BindAxis("MoveForward", this, &APortChar::MoveForward); | |
InputComponent->BindAxis("MoveRight", this, &APortChar::MoveRight); | |
//setup look bindings | |
InputComponent->BindAxis("Turn", this, &APortChar::AddControllerYawInput); | |
InputComponent->BindAxis("LookUp", this, &APortChar::AddControllerPitchInput); | |
//jump | |
InputComponent->BindAction("Jump", IE_Pressed, this, &APortChar::OnStartJump); | |
InputComponent->BindAction("Jump", IE_Released, this, &APortChar::OnStopJump); | |
//sprint | |
InputComponent->BindAction("Sprint", IE_Pressed, this, &APortChar::StartSprint); | |
InputComponent->BindAction("Sprint", IE_Released, this, &APortChar::StopSprint); | |
//E Interact button | |
InputComponent->BindAction("EInteract", IE_Pressed, this, &APortChar::Interaction); | |
///Crouch | |
InputComponent->BindAction("Crouch", IE_Pressed, this, &APortChar::StartCrouch); | |
InputComponent->BindAction("Crouch", IE_Released, this, &APortChar::StopCrouch); | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: Moves the player forward at speeds depending on whether they are sprinting | |
//----------------------------------------------------------------------------- | |
void APortChar::MoveForward(float Value) | |
{ | |
//add movement forward or backward | |
FRotator Rotation = Controller->GetControlRotation(); //gets the player rotation | |
Rotation.Pitch = 0.0f; | |
const FVector Direction = FRotationMatrix(Rotation).GetScaledAxis(EAxis::X); //gets the forward direction +x | |
AddMovementInput(Direction, Value); //adds the movement scaled by the value parameter | |
//sprint | |
if (bIsCrouching) | |
{ | |
PlayerCamera->StopAllInstancesOfCameraShake(SprintCameraShake, true); //stop sprint camera shake | |
} | |
if (Value == 1 && GetCharacterMovement()->IsMovingOnGround() == true) //is W being pressed and is the character on the ground? | |
{ | |
isMovingForwardOrBack = true; //then the player is moving forward. this is used to detect any movement | |
isMovingForward = true; //looks weird but this is used to detect only forward movement | |
if (isRunning == true)//if the player wants to sprint. set to true by StartSprint() if the shift button is being held | |
{ | |
if (!bIsCrouching) | |
{ | |
GetCharacterMovement()->MaxWalkSpeed = SprintSpeed; //sprint | |
PlayerCamera->PlayCameraShake(SprintCameraShake, 0.8f);//play sprint camera shake | |
stepRate = SprintRate; //fix footsteps to sprint rate | |
} | |
} | |
else //when shift is not being held | |
{ | |
if (!bIsCrouching) | |
{ | |
GetCharacterMovement()->MaxWalkSpeed = WalkSpeed; | |
PlayerCamera->StopAllInstancesOfCameraShake(SprintCameraShake, true); //stop sprint camera shake | |
stepRate = WalkRate;//fix footsteps to sprint rate | |
PlayerCamera->PlayCameraShake(CameraShakeX, 0.23f); //begin playing walking camera shake | |
} | |
} | |
} | |
else | |
isMovingForward = false; //the plays is not moving forward. Could be moving other directions | |
if (Value == -1 && GetCharacterMovement()->IsMovingOnGround() == true) //is the player on the ground and pressing S? | |
{ | |
PlayerCamera->PlayCameraShake(CameraShakeX, 0.23f); //walk camera shake | |
isMovingForwardOrBack = true; //he's moving back | |
stepRate = WalkRate; //fix foot sounds to walk rate | |
} | |
if (Value == 0.0f || GetCharacterMovement()->IsMovingOnGround() == false) //if the player is in the air or not moving | |
{ | |
PlayerCamera->StopAllInstancesOfCameraShake(CameraShakeX, true); //stop walk shake | |
PlayerCamera->StopAllInstancesOfCameraShake(SprintCameraShake, true); //stop sprint shake | |
isMovingForwardOrBack = false; //he aint moving, jim | |
stepRate = WalkRate; //set foot interval to walk rate | |
} | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: Moves the player left or right at a constant speed | |
//----------------------------------------------------------------------------- | |
void APortChar::MoveRight(float Value) | |
{ | |
//find out which way is "right" and move that way | |
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y); //finds right vector | |
AddMovementInput(Direction, Value); //moves in that direction scaled by Value. So he moves left is value > 0 | |
if (Value == 1 || Value == -1) //if the player is pressing a or d | |
{ | |
if (GetCharacterMovement()->IsMovingOnGround() == true) //and if he's on the ground | |
{ | |
PlayerCamera->PlayCameraShake(CameraShakeY, 0.23f); //play walk shake | |
isMovingLeftOrRight = true; //he's moving left or right | |
} | |
} | |
if (Value == 0.0f || GetCharacterMovement()->IsMovingOnGround() == false) //if he's still or in the air | |
{ | |
PlayerCamera->StopAllInstancesOfCameraShake(CameraShakeY, true); //stop the shakes, brah. it's cold | |
isMovingLeftOrRight = false; //he aint moving, Jimbo | |
} | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: Starts sprinting | |
//----------------------------------------------------------------------------- | |
void APortChar::StartSprint() | |
{ | |
if (isMovingForward == true) //now we see why I have a different variable for forward movement. | |
{ | |
isRunning = true; //sets isrunning to true only if the player is pressing W | |
} | |
if (!bIsCrouching) | |
{ | |
GetCharacterMovement()->MaxWalkSpeed = SprintSpeed; | |
} | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: ends the sprinting | |
//----------------------------------------------------------------------------- | |
void APortChar::StopSprint() | |
{ | |
isRunning = false; | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: function sets up the timer that plays the footsteps depending on whether the timer is expired | |
// and whether the player is moving | |
//----------------------------------------------------------------------------- | |
void APortChar::PlayFootsteps() | |
{ | |
//if the timer is not expired | |
if (bCanStep == true) | |
{ //is the player moving | |
if (isMoving == true) | |
{ | |
//if the foosteps sound is not initialized | |
if (StepSoundGrass != nullptr && StepSoundSnow != nullptr && StepSoundStone != nullptr) | |
{ | |
PlaySound(); | |
} | |
bCanStep = false; //turn the timer off | |
World->GetTimerManager().SetTimer(TimerHandle_StepRate, this, &APortChar::StepTimerExpired, stepRate);//setup timer and run function at an interval | |
} | |
} | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: play step | |
//----------------------------------------------------------------------------- | |
void APortChar::PlaySound() | |
{ | |
if (StepType == 0) //if steptype == 0. They're walking on stone or gravel | |
{ | |
UGameplayStatics::PlaySoundAttached(StepSoundStone, GetRootComponent()); | |
} | |
if (StepType == 1) //if it's 1. They're walking on snow | |
{ | |
UGameplayStatics::PlaySoundAttached(StepSoundSnow, GetRootComponent()); | |
} | |
if (StepType == 2)// if it's 2, they're walking on grass | |
{ | |
UGameplayStatics::PlaySoundAttached(StepSoundGrass, GetRootComponent()); | |
} | |
if (StepType == 3) //if its 3, they're walking on grass | |
{ | |
UGameplayStatics::PlaySoundAttached(StepSoundTile, GetRootComponent()); | |
} | |
} | |
//----------------------------------------------------------------------------- | |
// Purpose: resets timer. | |
//----------------------------------------------------------------------------- | |
void APortChar::StepTimerExpired() | |
{ | |
bCanStep = true; | |
} | |
//----------------------------------------------------------------------------- | |
//Purpose: Plays sound DEPRECATED: Used for snow demo. Not a part of controller | |
//---------------------------------------------------------------------------- | |
/* | |
void APortChar::PlayPiano() | |
{ | |
if (PianoSound != nullptr) | |
{ | |
UGameplayStatics::PlaySoundAtLocation(this, PianoSound, GetActorLocation()); | |
} | |
} | |
*/ | |
//----------------------------------------------------------------------------- | |
//Purpose: start jump | |
//---------------------------------------------------------------------------- | |
void APortChar::OnStartJump() | |
{ | |
if (GetCharacterMovement()->IsMovingOnGround()) //is player on the ground? | |
{ | |
bPressedJump = true; // jump | |
if (StepType == 0) //if steptype == 0. They're walking on stone or gravel | |
{ | |
UGameplayStatics::PlaySoundAttached(JumpSoundStone, GetRootComponent()); | |
} | |
if (StepType == 1) | |
{ | |
UGameplayStatics::PlaySoundAttached(JumpSoundSnow, GetRootComponent()); | |
} | |
if (StepType == 2) | |
{ | |
UGameplayStatics::PlaySoundAttached(StepSoundGrass, GetRootComponent()); | |
} | |
if (StepType == 3) | |
{ | |
UGameplayStatics::PlaySoundAttached(JumpSoundTile, GetRootComponent()); | |
} | |
} | |
} | |
//----------------------------------------------------------------------------- | |
//Purpose: stop jump | |
//---------------------------------------------------------------------------- | |
void APortChar::OnStopJump() | |
{ | |
bPressedJump = false; | |
} | |
//----------------------------------------------------------------------------- | |
//Purpose: when the player lands | |
//---------------------------------------------------------------------------- | |
void APortChar::Landed(const FHitResult &Hit) | |
{ | |
if (StepType == 0) //if steptype == 0. They're walking on stone or gravel | |
{ | |
UGameplayStatics::PlaySoundAtLocation(this, JumpSoundStone, GetActorLocation()); | |
} | |
if (StepType == 1) | |
{ | |
UGameplayStatics::PlaySoundAtLocation(this, JumpSoundSnow, GetActorLocation()); | |
} | |
if (StepType == 2) | |
{ | |
UGameplayStatics::PlaySoundAtLocation(this, StepSoundGrass, GetActorLocation()); | |
} | |
if (StepType == 3) | |
{ | |
UGameplayStatics::PlaySoundAtLocation(this, JumpSoundTile, GetActorLocation()); | |
} | |
} | |
//----------------------------------------------------------------------------- | |
//Purpose: when the player wants to interact with something | |
//---------------------------------------------------------------------------- | |
void APortChar::Interaction() | |
{ | |
if (ActorToInteractWith != nullptr) | |
{ | |
ActorToInteractWith->Output(); | |
} | |
} | |
//----------------------------------------------------------------------------- | |
//Purpose: Starts crouch | |
//---------------------------------------------------------------------------- | |
void APortChar::StartCrouch() | |
{ | |
bIsCrouching = true; | |
GetCharacterMovement()->MaxWalkSpeed = CrouchSpeed; | |
stepRate = CrouchRate; | |
} | |
void APortChar::StopCrouch() | |
{ | |
bIsCrouching = false; | |
GetCharacterMovement()->MaxWalkSpeed = WalkSpeed; | |
stepRate = WalkRate; | |
} | |
void APortChar::CrouchImpl(float DeltaTime) | |
{ | |
const float TargetBEH = bIsCrouching ? CrouchedEyeHeight : DecBEH; | |
const float TargetCapsuleSize = bIsCrouching ? GetCharacterMovement()->CrouchedHalfHeight : DecCapsHeight; | |
BaseEyeHeight = FMath::FInterpTo(BaseEyeHeight, TargetBEH, DeltaTime, 10.0f); | |
GetCapsuleComponent()->SetCapsuleHalfHeight(FMath::FInterpTo(GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(), TargetCapsuleSize, DeltaTime, 10.0f), true); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment