Created
July 13, 2017 15:28
-
-
Save Tim-Machine/1453d892eb492a615c7ed35e8491d211 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; | |
} | |
} |
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. | |
#pragma once | |
#include "CoreMinimal.h" | |
#include "GameFramework/Character.h" | |
#include "Camera/CameraComponent.h" | |
#include "PickUpItem.h" | |
#include "FPSCharacter.generated.h" | |
#define MAX_INVENTORY_ITEMS 4 | |
UCLASS() | |
class FPSPROJECT_API AFPSCharacter : public ACharacter | |
{ | |
GENERATED_BODY() | |
public: | |
// Sets default values for this character's properties | |
AFPSCharacter(); | |
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; | |
UFUNCTION() | |
void MoveForward(float Value); | |
UFUNCTION() | |
void MoveRight(float Value); | |
UFUNCTION() | |
void StartJump(); | |
UFUNCTION() | |
void StopJump(); | |
UFUNCTION() | |
void Fire(); | |
// handles the pickup input | |
UFUNCTION() | |
void PickupItem(); | |
// FPS camera. | |
UPROPERTY(VisibleAnywhere) | |
UCameraComponent* FPSCameraComponent; | |
UPROPERTY(VisibleDefaultsOnly, Category = Mesh) | |
USkeletalMeshComponent* FPSMesh; | |
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay) | |
FVector MuzzleOffset; | |
UPROPERTY(EditDefaultsOnly, Category = Projectile) | |
TSubclassOf<class AFPSProjectile> ProjectileClass; | |
UPROPERTY(EditAnywhere) | |
float RaycastRange = 250.0f; | |
// inventory | |
UPROPERTY(VisibleAnywhere) | |
TArray<APickUpItem*> Inventory; | |
UFUNCTION() | |
void HandleInventoryInput(); | |
TArray<APickUpItem*> GetInventory(); | |
private: | |
void Raycast(); | |
APickUpItem* LastItemSeen; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment