-
-
Save Tim-Machine/5991192cedf47de73d7ad31a4ec527af to your computer and use it in GitHub Desktop.
This file contains hidden or 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
// Fill out your copyright notice in the Description page of Project Settings. | |
#include "FPSCharacter.h" | |
#include "FPSProjectile.h" | |
#include "Engine.h" | |
#include "MyPlayerController.h" | |
#include "Components/CapsuleComponent.h" | |
// Sets default values | |
AFPSCharacter::AFPSCharacter() | |
{ | |
// 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; | |
// Create a first person camera component. | |
FPSCameraComponent = CreateDefaultSubobject<UCameraComponent>(TEXT("FirstPersonCamera")); | |
// Attach the camera component to our capsule component. | |
FPSCameraComponent->SetupAttachment(GetCapsuleComponent()); | |
// Position the camera slightly above the eyes. | |
FPSCameraComponent->SetRelativeLocation(FVector(0.0f, 0.0f, 50.0f + BaseEyeHeight)); | |
// Allow the pawn to control camera rotation. | |
FPSCameraComponent->bUsePawnControlRotation = true; | |
// Create a first person mesh component for the owning player. | |
FPSMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("FirstPersonMesh")); | |
// Only the owning player sees this mesh. | |
FPSMesh->SetOnlyOwnerSee(true); | |
// Attach the FPS mesh to the FPS camera. | |
FPSMesh->SetupAttachment(FPSCameraComponent); | |
// Disable some environmental shadowing to preserve the illusion of having a single mesh. | |
FPSMesh->bCastDynamicShadow = false; | |
FPSMesh->CastShadow = false; | |
// The owning player doesn't see the regular (third-person) body mesh. | |
GetMesh()->SetOwnerNoSee(true); | |
} | |
// Called when the game starts or when spawned | |
void AFPSCharacter::BeginPlay() | |
{ | |
Super::BeginPlay(); | |
if (GEngine) | |
{ | |
// Put up a debug message for five seconds. The -1 "Key" value (first argument) indicates that we will never need to update or refresh this message. | |
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("We are using FPSCharacter.")); | |
} | |
// used for inventory && pickup system | |
LastItemSeen = nullptr; | |
// initialze our inventory | |
Inventory.SetNum(MAX_INVENTORY_ITEMS); | |
} | |
// Called every frame | |
void AFPSCharacter::Tick(float DeltaTime) | |
{ | |
Super::Tick(DeltaTime); | |
// raycast every frame. | |
Raycast(); | |
} | |
// Called to bind functionality to input | |
void AFPSCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent) | |
{ | |
Super::SetupPlayerInputComponent(PlayerInputComponent); | |
// movement | |
PlayerInputComponent->BindAxis("MoveForward", this, &AFPSCharacter::MoveForward); | |
PlayerInputComponent->BindAxis("MoveRight", this, &AFPSCharacter::MoveRight); | |
// looking | |
PlayerInputComponent->BindAxis("Turn", this, &AFPSCharacter::AddControllerYawInput); | |
PlayerInputComponent->BindAxis("LookUp", this, &AFPSCharacter::AddControllerPitchInput); | |
// jump action | |
PlayerInputComponent->BindAction("Jump", IE_Pressed, this, &AFPSCharacter::StartJump); | |
PlayerInputComponent->BindAction("Jump", IE_Released, this, &AFPSCharacter::StopJump); | |
PlayerInputComponent->BindAction("Fire", IE_Pressed, this, &AFPSCharacter::Fire); | |
// interaction button | |
PlayerInputComponent->BindAction("Interaction", IE_Pressed, this, &AFPSCharacter::PickupItem); | |
// inventory action | |
PlayerInputComponent->BindAction("Inventory",IE_Pressed, this, &AFPSCharacter::HandleInventoryInput); | |
} | |
void AFPSCharacter::MoveForward(float Value) { | |
// find out which way is "forward" and record that the player wants to move that way. | |
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::X); | |
AddMovementInput(Direction, Value); | |
} | |
void AFPSCharacter::MoveRight(float Value) { | |
FVector Direction = FRotationMatrix(Controller->GetControlRotation()).GetScaledAxis(EAxis::Y); | |
AddMovementInput(Direction, Value); | |
} | |
void AFPSCharacter::StartJump() | |
{ | |
bPressedJump = true; | |
} | |
void AFPSCharacter::StopJump() | |
{ | |
bPressedJump = false; | |
} | |
void AFPSCharacter::Fire() | |
{ | |
if (ProjectileClass) { | |
FVector CameraLocation; | |
FRotator CameraRotation; | |
GetActorEyesViewPoint(CameraLocation, CameraRotation); | |
// transform muzzleoffset from camera space to world space | |
FVector MuzzleLocation = CameraLocation + FTransform(CameraRotation).TransformVector(MuzzleOffset); | |
FRotator MuzzleRotation = CameraRotation; | |
// skew aim to be slightly upwards | |
MuzzleRotation.Pitch += 10.0f; | |
UWorld* World = GetWorld(); | |
if (World) { | |
FActorSpawnParameters SpawnParams; | |
SpawnParams.Owner = this; | |
SpawnParams.Instigator = Instigator; | |
// spawn the projectile at the muzzle | |
AFPSProjectile* Projectile = World->SpawnActor<AFPSProjectile>(ProjectileClass, MuzzleLocation, MuzzleRotation, SpawnParams); | |
if (Projectile) { | |
// set the projectil's init trajectory. | |
FVector LaunchDirection = MuzzleRotation.Vector(); | |
Projectile->FireInDirection(LaunchDirection); | |
} | |
} | |
} | |
} | |
void AFPSCharacter::PickupItem() | |
{ | |
if (LastItemSeen) { | |
// find the first avaible slot | |
int32 AvailableSlot = Inventory.Find(nullptr); | |
if (AvailableSlot != INDEX_NONE) { | |
// ADD item to the first valid slot | |
Inventory[AvailableSlot] = LastItemSeen; | |
FString ItemName = LastItemSeen->GetName(); | |
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, ItemName); | |
// destory item from game; | |
LastItemSeen->Destroy(); | |
} | |
else { | |
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("You can not carry anymore items")); | |
} | |
} | |
} | |
void AFPSCharacter::HandleInventoryInput() | |
{ | |
GEngine->AddOnScreenDebugMessage(-1, 5.0f, FColor::Red, TEXT("inventory one")); | |
AMyPlayerController* Con = Cast<AMyPlayerController>(GetController()); | |
if(Con) Con->HandleInventoryInput(); | |
} | |
TArray<APickUpItem*> AFPSCharacter::GetInventory() | |
{ | |
return Inventory; | |
} | |
void AFPSCharacter::Raycast() | |
{ | |
//calculating start and end location | |
FVector StartLocation = FPSCameraComponent->GetComponentLocation(); | |
FVector EndLocation = StartLocation + (FPSCameraComponent->GetForwardVector() * RaycastRange); | |
FHitResult RaycastHit; | |
// Raycast should ignore the character | |
FCollisionQueryParams CQP; | |
CQP.AddIgnoredActor(this); | |
GetWorld()->LineTraceSingleByChannel(RaycastHit, StartLocation, EndLocation, ECollisionChannel::ECC_WorldDynamic); | |
APickUpItem* Pickup = Cast<APickUpItem>(RaycastHit.GetActor()); | |
if (LastItemSeen && LastItemSeen != Pickup){ | |
// if our character sees a differnt pickup then disable the glowing affec on the previous seen item | |
LastItemSeen->SetGlowEffect(false); | |
} | |
if (Pickup) { | |
//Enable the glow effe on the current item | |
LastItemSeen = Pickup; | |
Pickup->SetGlowEffect(true); | |
} | |
else { // re-initialize | |
LastItemSeen = nullptr; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment