OK so here’s what I have
TesterCharacter.h
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#pragma once
#include "GameFramework/Character.h"
#include "Weapon.h"
#include "Item.h"
#include "Knife.h"
#include "TesterCharacter.generated.h"
UCLASS(config=Game)
class ATesterCharacter : public ACharacter
{
GENERATED_BODY()
/** Pawn mesh: 1st person view (arms; seen only by self) */
UPROPERTY(VisibleDefaultsOnly, Category=Mesh)
class USkeletalMeshComponent* Mesh1P;
UPROPERTY(VisibleDefaultsOnly, Category = Collision)
class UBoxComponent *CollisionComp;
/** First person camera */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Camera, meta = (AllowPrivateAccess = "true"))
class UCameraComponent* FirstPersonCameraComponent;
public:
ATesterCharacter(const FObjectInitializer& ObjectInitializer);
/** Base turn rate, in deg/sec. Other scaling may affect final turn rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseTurnRate;
/** Base look up/down rate, in deg/sec. Other scaling may affect final rate. */
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category=Camera)
float BaseLookUpRate;
/** Gun muzzle's offset from the characters location */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay)
FVector GunOffset;
/** Projectile class to spawn */
UPROPERTY(EditDefaultsOnly, Category=Projectile)
TSubclassOf<class ATesterProjectile> ProjectileClass;
/** Sound to play each time we fire */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category=Gameplay)
class USoundBase* FireSound;
/** AnimMontage to play each time we fire */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Gameplay)
class UAnimMontage* FireAnimation;
//Stores Currently Equiped Weapon Information(to access functions, variables, etc)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Weapon)
AWeapon *CurrentWeapon;
//Inventory for the Weapons
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Inventory)
TArray<TSubclassOf<AWeapon>> WeapInventory;
UPROPERTY(VisibleAnyWhere, BlueprintReadOnly, Category = Inventory)
TArray<class AWeapon*> Inventory;
//Inventory for Key Items
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Inventory)
TArray<TSubclassOf<AItem>> ItemInventory;
TSubclassOf<AKnife> Knife_D;
UPROPERTY(EditDefaultsOnly, Category = Inventory)
TArray<TSubclassOf<AWeapon>> DefaultInventory;
void GiveDefaultWeapons();
//Tells Inventory if that weapon is already in inventory. If it is, the function will then add ammo. If ammo is full, it will then not process the pickup
void ProcessWeaponPickup(AWeapon *Weapon);
AWeapon* GetPreviousWeapon();
AWeapon* GetNextWeapon();
void NextWeapon();
void PrevWeapon();
void ProcessItemPickup(AItem *Item);
void EquipWeapon(AWeapon *Weapon);
virtual void BeginPlay() override;
protected:
/** Handler for a touch input beginning. */
void TouchStarted(const ETouchIndex::Type FingerIndex, const FVector Location);
/** Fires a projectile. */
void OnFire();
/** Handles moving forward/backward */
void MoveForward(float Val);
/** Handles stafing movement, left and right */
void MoveRight(float Val);
/**
* Called via input to turn at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void TurnAtRate(float Rate);
/**
* Called via input to turn look up/down at a given rate.
* @param Rate This is a normalized rate, i.e. 1.0 means 100% of desired turn rate
*/
void LookUpAtRate(float Rate);
protected:
// APawn interface
virtual void SetupPlayerInputComponent(class UInputComponent* InputComponent) override;
// End of APawn interface
UFUNCTION()
void OnCollision(AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult);
public:
/** Returns Mesh1P subobject **/
FORCEINLINE class USkeletalMeshComponent* GetMesh1P() const { return Mesh1P; }
/** Returns FirstPersonCameraComponent subobject **/
FORCEINLINE class UCameraComponent* GetFirstPersonCameraComponent() const { return FirstPersonCameraComponent; }
};
TesterCharacter.cpp
// Copyright 1998-2014 Epic Games, Inc. All Rights Reserved.
#include "Tester.h"
#include "TesterCharacter.h"
#include "TesterProjectile.h"
#include "Animation/AnimInstance.h"
//////////////////////////////////////////////////////////////////////////
// ATesterCharacter
ATesterCharacter::ATesterCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
static ConstructorHelpers::FObjectFinder<UBlueprint>BP_Knife(TEXT("Blueprint'/Game/Blueprints/Weapon/Knife/Knife_BP.Knife_BP'"));
if (BP_Knife.Succeeded())
{
Knife_D = (UClass*)BP_Knife.Object->GeneratedClass;
}
// Set size for collision capsule
GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
// set our turn rates for input
BaseTurnRate = 45.f;
BaseLookUpRate = 45.f;
WeapInventory.SetNum(10, false);
Inventory.SetNum(10, false);
CurrentWeapon = NULL;
// Create a CameraComponent
FirstPersonCameraComponent = ObjectInitializer.CreateDefaultSubobject<UCameraComponent>(this, TEXT("FirstPersonCamera"));
FirstPersonCameraComponent->AttachParent = GetCapsuleComponent();
FirstPersonCameraComponent->RelativeLocation = FVector(0, 0, 64.f); // Position the camera
FirstPersonCameraComponent->bUsePawnControlRotation = true;
// Default offset from the character location for projectiles to spawn
GunOffset = FVector(100.0f, 30.0f, 10.0f);
// Create a mesh component that will be used when being viewed from a '1st person' view (when controlling this pawn)
Mesh1P = ObjectInitializer.CreateDefaultSubobject<USkeletalMeshComponent>(this, TEXT("CharacterMesh1P"));
Mesh1P->SetOnlyOwnerSee(true); // only the owning player will see this mesh
Mesh1P->AttachParent = FirstPersonCameraComponent;
Mesh1P->RelativeLocation = FVector(0.f, 0.f, -150.f);
Mesh1P->bCastDynamicShadow = false;
Mesh1P->CastShadow = false;
CollisionComp = ObjectInitializer.CreateDefaultSubobject<UBoxComponent>(this, TEXT("CollisionComp"));
CollisionComp->AttachParent = RootComponent;
CollisionComp->OnComponentBeginOverlap.AddDynamic(this, &ATesterCharacter::OnCollision);
// Note: The ProjectileClass and the skeletal mesh/anim blueprints for Mesh1P are set in the
// derived blueprint asset named MyCharacter (to avoid direct content references in C++)
}
void ATesterCharacter::BeginPlay()
{
GiveDefaultWeapons();
}
void ATesterCharacter::GiveDefaultWeapons()
{
for (int32 i = 0; i < 1; i++)
{
if (DefaultInventory*)
{
AWeapon *Spawner = GetWorld()->SpawnActor<AWeapon>(DefaultInventory*);
if (Spawner)
{
Inventory* = Spawner;
CurrentWeapon = Inventory*;
Inventory*->CollisionComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
Inventory*->AttachRootComponentTo(GetMesh1P(), "WeapSocket", EAttachLocation::SnapToTarget);
}
}
}
}
//////////////////////////////////////////////////////////////////////////
// Input
void ATesterCharacter::SetupPlayerInputComponent(class UInputComponent* InputComponent)
{
// set up gameplay key bindings
check(InputComponent);
InputComponent->BindAction("Jump", IE_Pressed, this, &ACharacter::Jump);
InputComponent->BindAction("Jump", IE_Released, this, &ACharacter::StopJumping);
InputComponent->BindAction("PreviousWeapon", IE_Pressed, this, &ATesterCharacter::PrevWeapon);
InputComponent->BindAction("NextWeapon", IE_Pressed, this, &ATesterCharacter::NextWeapon);
InputComponent->BindAction("Fire", IE_Pressed, this, &ATesterCharacter::OnFire);
InputComponent->BindTouch(EInputEvent::IE_Pressed, this, &ATesterCharacter::TouchStarted);
InputComponent->BindAxis("MoveForward", this, &ATesterCharacter::MoveForward);
InputComponent->BindAxis("MoveRight", this, &ATesterCharacter::MoveRight);
// We have 2 versions of the rotation bindings to handle different kinds of devices differently
// "turn" handles devices that provide an absolute delta, such as a mouse.
// "turnrate" is for devices that we choose to treat as a rate of change, such as an analog joystick
InputComponent->BindAxis("Turn", this, &APawn::AddControllerYawInput);
InputComponent->BindAxis("TurnRate", this, &ATesterCharacter::TurnAtRate);
InputComponent->BindAxis("LookUp", this, &APawn::AddControllerPitchInput);
InputComponent->BindAxis("LookUpRate", this, &ATesterCharacter::LookUpAtRate);
}
void ATesterCharacter::OnFire()
{
if (CurrentWeapon != NULL)
{
CurrentWeapon->Fire();
}
}
void ATesterCharacter::OnCollision(AActor *OtherActor, UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)
{
AWeapon *Weapon = Cast<AWeapon>(OtherActor);
if (Weapon)
{
ProcessWeaponPickup(Weapon);
}
}
void ATesterCharacter::ProcessWeaponPickup(AWeapon *Weapon)
{
if (Weapon != NULL)
{
//Check to see if Weapon is not currently in the priority slot in Array (basically checks to see if weapon is in the array)
if (Inventory[Weapon->WeapConfig.Priority] != Weapon)
{
//Insert Weapon in correct slot by priority
WeapInventory.Insert(Weapon->GetClass(), Weapon->WeapConfig.Priority);
Inventory.Insert(Weapon, Weapon->WeapConfig.Priority);
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Black, "You Just picked up a " + Inventory[Weapon->WeapConfig.Priority]->WeapConfig.Name);
//Checks to see if the weapon is a higher priority number
if (Weapon->WeapConfig.Priority > Inventory[CurrentWeapon->WeapConfig.Priority]->WeapConfig.Priority)
{
//Equip weapon with the higher priority
EquipWeapon(Inventory[Weapon->WeapConfig.Priority]);
}
//Destroy the picked up weapon on the scene
Weapon->Destroy();
}
else
{
if (Inventory[Weapon->WeapConfig.Priority]->CurrentAmmo >= 0 && Weapon->CurrentAmmo <= (Inventory[Weapon->WeapConfig.Priority]->WeapConfig.MaxAmmo - Inventory[Weapon->WeapConfig.Priority]->CurrentAmmo))
{
Inventory[Weapon->WeapConfig.Priority]->CurrentAmmo += Weapon->CurrentAmmo;
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Black, "Added " + Weapon->CurrentAmmo);
Weapon->Destroy();
}
else
{
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Black, "Full Ammo on " + WeapInventory[Weapon->WeapConfig.Priority]->GetDefaultObject<AWeapon>()->WeapConfig.Name);
}
}
}
}
void ATesterCharacter::ProcessItemPickup(AItem *Item)
{
}
void ATesterCharacter::NextWeapon()
{
if (GetNextWeapon() != NULL && GetNextWeapon() != CurrentWeapon)
{
EquipWeapon(GetNextWeapon());
}
}
void ATesterCharacter::PrevWeapon()
{
if (GetPreviousWeapon() != NULL && CurrentWeapon != GetPreviousWeapon())
{
EquipWeapon(GetPreviousWeapon());
}
}
AWeapon* ATesterCharacter::GetPreviousWeapon()
{
if (Inventory[CurrentWeapon->WeapConfig.Priority - 1] < 0)
{
return Inventory[CurrentWeapon->WeapConfig.Priority];
}
else
{
return Inventory[CurrentWeapon->WeapConfig.Priority - 1];
}
}
AWeapon* ATesterCharacter::GetNextWeapon()
{
if (Inventory[CurrentWeapon->WeapConfig.Priority + 1] == NULL)
{
return Inventory[CurrentWeapon->WeapConfig.Priority];
}
else
{
return Inventory[CurrentWeapon->WeapConfig.Priority + 1];
}
}
void ATesterCharacter::EquipWeapon(AWeapon *Weapon)
{
if (CurrentWeapon != NULL)
//store the current weapon in it's correct inventory slot
CurrentWeapon = Inventory[CurrentWeapon->WeapConfig.Priority];
//destroy the current weapon on the scene
CurrentWeapon->Destroy();
Inventory[Weapon->WeapConfig.Priority]->WeapConfig.bIsEquipped = true;
AWeapon *Spawner = GetWorld()->SpawnActor<AWeapon>(Weapon->GetClass());
if (Spawner)
{
Inventory[Weapon->WeapConfig.Priority] = Spawner;
Spawner->CollisionComp->SetCollisionEnabled(ECollisionEnabled::NoCollision);
GEngine->AddOnScreenDebugMessage(-1, 2.f, FColor::Black, "Spawned");
CurrentWeapon = Inventory[Weapon->WeapConfig.Priority];
Inventory[Weapon->WeapConfig.Priority]->AttachRootComponentTo(GetMesh1P(), "WeapSocket", EAttachLocation::SnapToTarget);
}
}
}
now the issue is the check on the Inventory if I already have the weapon. It keeps thinking I dont have the weapon in that slot. Need to do this so I know it’s checking the information correctly when trying to pick up ammo.
On another side of it besides that
I switched weapons back and forth, it still wont keep the information correctly :/.