Hey! Thanks for the quick reply
So I have my character class, gun class and projectile class. I created the static mesh and projectile movement component within the projectile class as well as setting initial speed and max speed. I then have a “Pull trigger” function and a “gun trace” function in the gun class which spawns the projectile and adds damage. I then have a “fire” function within the character class that calls the “pull trigger” function. I’ll leave some code here so that it hopefully makes sense, because I know I’m not the best at explaining/describing things haha
for the projectile:
AProjectile::AProjectile()
{
PrimaryActorTick.bCanEverTick = true;
ProjectileMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Projectile Mesh"));
RootComponent = ProjectileMesh;
ProjectileMovementComponent = CreateDefaultSubobject<UProjectileMovementComponent>(TEXT("Projectile Movement Component"));
ProjectileMovementComponent->MaxSpeed = 5000;
ProjectileMovementComponent->InitialSpeed = 3000;
}
// Called when the game starts or when spawned
void AProjectile::BeginPlay()
{
Super::BeginPlay();
ProjectileMesh->OnComponentHit.AddDynamic(this, &AProjectile::OnHit);
}
// Called every frame
void AProjectile::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AProjectile::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor, UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit)
{
AActor* MyOwner = GetOwner();
if (MyOwner == nullptr)
{
return;
}
AController* MyOwnerInstigator = MyOwner->GetInstigatorController();
UClass* DamageTypeClass = UDamageType::StaticClass();
if (OtherActor && OtherActor != this && OtherActor != MyOwner)
{
UGameplayStatics::ApplyDamage(OtherActor, Damage, MyOwnerInstigator, this, DamageTypeClass);
Destroy();
}
}
for the gun:
AGun::AGun()
{
// 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;
Root = CreateDefaultSubobject<USceneComponent>(TEXT("Root"));
SetRootComponent(Root);
Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
Mesh->SetupAttachment(Root);
ProjectileSpawnPoint = CreateDefaultSubobject<USceneComponent>(TEXT("Spawn Point"));
ProjectileSpawnPoint->SetupAttachment(Mesh);
}
// Called when the game starts or when spawned
void AGun::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AGun::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void AGun::PullTrigger()
{
UGameplayStatics::SpawnEmitterAttached(MuzzleFlash, Mesh, TEXT(“MuzzleFlashSocket”));
FVector ProjectileLocation = ProjectileSpawnPoint->GetComponentLocation();
FRotator ProjectileRotation = ProjectileSpawnPoint->GetComponentRotation();
AProjectile* Projectile = GetWorld()->SpawnActor<AProjectile>(ProjectileClass, ProjectileLocation, ProjectileRotation); Projectile->SetOwner(this);
UGameplayStatics::SpawnEmitterAttached(ProjectileBeam, ProjectileSpawnPoint, TEXT("ProjectileBeamSocket"));
FHitResult Hit;
FVector ShotDirection;
bool bSuccess = GunTrace(Hit, ShotDirection);
if(bSuccess)
{
// UGameplayStatics::SpawnEmitterAtLocation(GetWorld(), ImpactEffect, Hit.Location, ShotDirection.Rotation());
// UGameplayStatics::PlaySoundAtLocation(GetWorld(), ImpactSound, Hit.Location);
AActor* HitActor = Hit.GetActor();
if (HitActor != nullptr)
{
FPointDamageEvent DamageEvent(Damage, Hit, ShotDirection, nullptr);
AController* OwnerController = GetOwnerController();
HitActor->TakeDamage(DamageAmount, DamageEvent, OwnerController, this);
}
}
Let me know if this helps or if I need to share anything else, and thanks again!
Edit: Forgot to add that I set my projectile spawn point at the gun barrel in Unreal Editor