I am trying to create a TArray Recoil Pattern for my Gun with 30 different FVector coordinates for each bullet. I went through tultorial videos and read Array Containers in Unreal Engine | Unreal Engine Documentation this guide for adding to the array.I tried using Add, Emplace, Innit to no avail. I even set the size to 30 with SetNum, still didn’t work i do not understand what my issue is with adding elements to the TArray. I keep getting this crash error :
this is my GunProperties.H:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "Camera/CameraComponent.h"
#include "GunProperties.generated.h"
#define TRACE_WEAPON ECC_GameTraceChannel1
UENUM(BlueprintType)
namespace EWeaponProjectile
{
enum ProjectileType
{
EBullet UMETA(DisplayName = "Bullet"),
ESpread UMETA(DisplayName = "Spread"),
EProjectile UMETA(DisplayName = "Projectile"),
};
}
USTRUCT()
struct FWeaponData
{
GENERATED_USTRUCT_BODY()
UPROPERTY(EditDefaultsOnly, Category = Ammo)
int32 MaxAmmo;
UPROPERTY(EditDefaultsOnly, Category = Config)
float TimeBetweenShots;
UPROPERTY(EditDefaultsOnly, Category = Ammo)
int32 ShotCost;
UPROPERTY(EditDefaultsOnly, Category = Config)
float WeaponRange;
UPROPERTY(EditDefaultsOnly, Category = Config)
float WeaponSpread;
UPROPERTY(EditDefaultsOnly, Category = Config)
float recoilResetTimeSeconds;
UPROPERTY(EditDefaultsOnly, Category = Config)
float lastTimeShotForAr;
};
UCLASS()
class PLAYERVSAI_API AGunProperties : public AActor
{
GENERATED_BODY()
public:
// Called when the game starts or when spawned
AGunProperties();
// Called every frame
UFUNCTION()
void Fire(const FVector CameraDir);
UFUNCTION()
void InstantFire(const FVector CameraDir);
virtual void BeginPlay() override;
UPROPERTY(EditDefaultsOnly, Category = Config)
FWeaponData WeaponConfig;
UPROPERTY(EditDefaultsOnly, BlueprintReadWrite, Category = Config)
TEnumAsByte<EWeaponProjectile::ProjectileType> ProjectileType;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Collision)
UBoxComponent* CollisionComp;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Config)
USkeletalMeshComponent* WeaponMesh;
/*void InterpAiming(float DeltaSeconds);
void InterpRelativeHand(float DeltaSeconds);*/
FTransform RecoilTransform;
FTransform FinalRecoilTransform;
//Handle Vector Recoil , returns New Location
protected:
FHitResult WeaponTrace(const FVector &TraceFrom, const FVector &TraceTo) const;
void HandleARShooting(UCameraComponent* Camera);
void ProcessInstantHit(const FHitResult& Impact, const FVector& Origin, const FVector& ShootDir, int32 RandomSeed, float RadicalSpread);
void ProcessInstantHitForAR(const FHitResult& Impact, const FVector& Origin);
TArray<FVector> RecoilPattern[];
};```
This is my GunProperties.cpp:
#include "GunProperties.h"
#include "Engine.h"
AGunProperties::AGunProperties()
{
PrimaryActorTick.bCanEverTick = false;
CollisionComp = CreateDefaultSubobject<UBoxComponent>(TEXT("CollisionComp"));
RootComponent = CollisionComp;
WeaponMesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Gun Mesh"));
WeaponMesh->AttachTo(RootComponent);
}
void AGunProperties::BeginPlay()
{
Super::BeginPlay();
if (ProjectileType == EWeaponProjectile::EBullet)
{
RecoilPattern->SetNum(30);
RecoilPattern->Emplace(FVector(-0.2, 0, 0));
RecoilPattern->Emplace(FVector(-0.2, 0, 0));
RecoilPattern->Emplace(FVector(-0.2, 0, 0));
RecoilPattern->Emplace(FVector(-0.2, 0, 0));
RecoilPattern->Emplace(FVector(-0.2, 0, 0));
RecoilPattern->Emplace(FVector(-0.2, 0, 0));
RecoilPattern->Emplace(FVector(-0.3, 0, 0));
RecoilPattern->Emplace(FVector(-0.3, 0, 0));
RecoilPattern->Emplace(FVector(-0.3, 0, 0));
RecoilPattern->Emplace(FVector(-0.3, 0, 0));
RecoilPattern->Emplace(FVector(-0.3, 0, 0));
RecoilPattern->Emplace(FVector(-0.3, 0, 0));
RecoilPattern->Emplace(FVector(-0.5, 0, 0));
RecoilPattern->Emplace(FVector(-0.5, 0, 0));
RecoilPattern->Emplace(FVector(-0.5, 0, 0));
RecoilPattern->Emplace(FVector(-0.5, 0, 0));
RecoilPattern->Emplace(FVector(-0.5, 0, 0));
RecoilPattern->Emplace(FVector(-0.5, 0, 0));
RecoilPattern->Emplace(FVector(0, -0.3, 0));
RecoilPattern->Emplace(FVector(0, -0.3, 0));
RecoilPattern->Emplace(FVector(0, -0.3, 0));
RecoilPattern->Emplace(FVector(0, -0.3, 0));
RecoilPattern->Emplace(FVector(0, -0.3, 0));
RecoilPattern->Emplace(FVector(0, -0.3, 0));
RecoilPattern->Emplace(FVector(0, 0.3, 0));
RecoilPattern->Emplace(FVector(0, 0.3, 0));
RecoilPattern->Emplace(FVector(0, 0.3, 0));
RecoilPattern->Emplace(FVector(0, 0.3, 0));
RecoilPattern->Emplace(FVector(0, 0.3, 0));
RecoilPattern->Emplace(FVector(0, 0.3, 0));
}
}
void AGunProperties::Fire( FVector CameraDir)
{
if (ProjectileType == EWeaponProjectile::EBullet)
{
GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Black, TEXT("Bullet"));
//InstantFire(CameraDir);
}
if (ProjectileType == EWeaponProjectile::ESpread)
{
GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Black, TEXT("Spread"));
for (int32 i = 0; i <= WeaponConfig.WeaponSpread; i++)
{
InstantFire(CameraDir);
}
}
if (ProjectileType == EWeaponProjectile::EProjectile)
{
GEngine->AddOnScreenDebugMessage(-1, 2.0f, FColor::Black, TEXT("Projectile"));
}
}
void AGunProperties::InstantFire( FVector CameraDir)
{
const int32 RandomSeed = FMath::Rand();
FRandomStream WeaponRandomStream(RandomSeed);
const float CurrentSpread = WeaponConfig.WeaponSpread;
const float SpreadCone = FMath::DegreesToRadians(WeaponConfig.WeaponSpread );
const FVector StartTrace = WeaponMesh->GetSocketLocation("MF");
const FVector ShootDir = WeaponRandomStream.VRandCone(StartTrace, SpreadCone, SpreadCone);
const FVector EndTrace = StartTrace + ShootDir * WeaponConfig.WeaponRange;
const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);
ProcessInstantHit(Impact, StartTrace, ShootDir, RandomSeed, CurrentSpread);
}
FHitResult AGunProperties::WeaponTrace(const FVector& TraceFrom, const FVector& TraceTo) const
{
static FName WeaponFireTag = FName(TEXT("WeaponTrace"));
FCollisionQueryParams TraceParams(WeaponFireTag, true);
TraceParams.bReturnPhysicalMaterial = true;
TraceParams.AddIgnoredActor(this);
FHitResult Hit(ForceInit);
GetWorld()->LineTraceSingleByChannel(Hit, TraceFrom, TraceTo, TRACE_WEAPON, TraceParams);
return Hit;
}
void AGunProperties::HandleARShooting(UCameraComponent* Camera)
{
if (GetWorld()->DeltaTimeSeconds - WeaponConfig.lastTimeShotForAr / WeaponConfig.TimeBetweenShots)
{
//We shoot
const FVector StartTrace = WeaponMesh->GetSocketLocation("MF");
const FVector ShootDir = FVector(StartTrace);
const FVector EndTrace = StartTrace * WeaponConfig.WeaponRange;
const FHitResult Impact = WeaponTrace(StartTrace, EndTrace);
ProcessInstantHitForAR(Impact, StartTrace);
WeaponConfig.lastTimeShotForAr = GetWorld()->DeltaTimeSeconds;
}
}
void AGunProperties::ProcessInstantHit(const FHitResult& Impact, const FVector& Origin, const FVector& ShootDir, int32 RandomSeed, float RadicalSpread)
{
const FVector EndTrace = Origin + ShootDir * WeaponConfig.WeaponRange;
const FVector EndPoint = Impact.GetActor() ? Impact.ImpactPoint : EndTrace;
DrawDebugLine(this->GetWorld(), Origin, Impact.TraceEnd, FColor::Black,false, 1000, 10.f);
}
void AGunProperties::ProcessInstantHitForAR(const FHitResult& Impact, const FVector& Origin)
{
const FVector EndTrace = Origin* WeaponConfig.WeaponRange;
const FVector EndPoint = Impact.GetActor() ? Impact.ImpactPoint : EndTrace;
DrawDebugLine(this->GetWorld(), Origin, Impact.TraceEnd, FColor::Black, false, 1000, 10.f);
}