Here I am creating a linetrace with the sideeffect to where if the line trace does not hit spawn a projectile. But the projectile spawns at the center of the map instead at the end of the line trace for some odd reason could it be the location of the end of the linetrace. I am sure I had made the end linetrace correctly. I set the spawnpoint of the object at the end of the line trace.
void AM4A1::Fire()
{
//Here is the raycast.
UGameplayStatics::SpawnEmitterAttached(MuzzleFlash, M4A1Mesh, FName("Muzzle1"));
FCollisionResponseParams ResponseParams;
FCollisionQueryParams AssaultRifleQueryParams = FCollisionQueryParams(SCENE_QUERY_STAT(WeaponTrace), false, this);
FActorSpawnParameters SpawnParams;
SpawnParams.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
AssaultRifleQueryParams.AddIgnoredComponent(M4A1Mesh);
for (uint8 i = 0; i < 4; ++i);
{
//This is so that the firearm has spread every four hits and is not completely accurate.
//FHitArray in order to penetrate objects until the last index of the array.
TArray<FHitResult> Hit1;
const FVector AssaultRifleStartTrace = M4A1Mesh->GetSocketLocation(FName("Muzzle1"));
FRotator CurrentRotation = M4A1Mesh->GetSocketRotation(FName("Muzzle1"));
CurrentRotation.Pitch = FMath::RandRange(CurrentRotation.Pitch - 3, CurrentRotation.Pitch + 3);
CurrentRotation.Yaw = FMath::RandRange(CurrentRotation.Yaw - 3, CurrentRotation.Yaw + 3);
FVector AssaultEndTrace = AssaultRifleStartTrace + CurrentRotation.Vector() * 1000.0f;
FVector Location = AssaultEndTrace;
//I would put get control rotation here, but the linetrace is inside the firearm itself.
FRotator Rotation = M4A1Mesh->GetRotation(FName("Muzzle1"));
DrawDebugLine(GetWorld(), AssaultRifleStartTrace, AssaultEndTrace, FColor(255, 0, 0), false, -1, 0, 12.333);
if (GetWorld()->LineTraceMultiByChannel(Hit1, AssaultRifleStartTrace, AssaultEndTrace, ECollisionChannel::ECC_Visibility, AssaultRifleQueryParams, ResponseParams))
{
for (FHitResult& Results : Hit1)
{
if (AActor* HitActor = Results.GetActor())
{
HitActor->Destroy();
}
}
}
//This is where the object spawns if the raycast does not hit it's mark.
else
{
if (M4A1Bullets != NULL)
{
UWorld* World = GetWorld();
if (World)
{
//This is where the object needs to spawn.
World->SpawnActor<AM4A1Bullets>(M4A1Bullets, //The location is correct I believe. Location, Rotation, SpawnParams);
}
}
}
if (GetWorld()->LineTraceMultiByChannel(Hit1, AssaultRifleStartTrace, AssaultEndTrace, ECollisionChannel::ECC_Visibility, AssaultRifleQueryParams, ResponseParams))
{
for (FHitResult& Results : Hit1)
{
if (ImpactParticles)
{
UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactParticles, FTransform(Results.ImpactNormal.Rotation(), Results.ImpactPoint));
}
}
}
}
}
Here is the Projectile Code .cpp.
//I don't know if using a scene component is the problem here.
AM4A1Bullets::AM4A1Bullets()
{
//I noticed that the scene component is causing the project to spawn in the center yet that mean I cannot rotate the bullet in the viewport.
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
M4A1BulletSceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComponent"));
RootComponent = M4A1BulletSceneComponent;
M4A1BulletMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("M4A1BulletMesh"));
M4A1ProjectileMovement = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("ProjectileComp"));
M4A1ProjectileMovement->InitialSpeed = 1000.0f;
M4A1ProjectileMovement->MaxSpeed = 1000.0f;
//M4A1ProjectileMovement->bRotationFollowsVelocity = true;
//M4A1ProjectileMovement->bShouldBounce = true;
}