// Fill out your copyright notice in the Description page of Project Settings. #include "ProjectileWeapon.h" #include "Projectile.h" #include "Engine/SkeletalMeshSocket.h" void AProjectileWeapon::Fire(const FVector& HitTarget) { Super::Fire(HitTarget); APawn* InstigatorPawn = Cast(GetOwner()); const USkeletalMeshSocket* MuzzleFlashSocket = GetWeaponMesh()->GetSocketByName(FName("MuzzleFlash")); UWorld* World = GetWorld(); if (MuzzleFlashSocket && World) { FTransform SocketTransform = MuzzleFlashSocket->GetSocketTransform(GetWeaponMesh()); // From muzzle flash socket to hit location from TraceUnderCrosshairs const FVector ToTarget = HitTarget - SocketTransform.GetLocation(); const FRotator TargetRotation = ToTarget.Rotation(); FActorSpawnParameters SpawnParams; SpawnParams.Owner = GetOwner(); SpawnParams.Instigator = InstigatorPawn; AProjectile* SpawnedProjectile = nullptr; if (bUseServerSideRewind) { if (InstigatorPawn->HasAuthority()) // Server { if (InstigatorPawn->IsLocallyControlled()) // Server, host - use replicated projectile { SpawnedProjectile = World->SpawnActor(ProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams); SpawnedProjectile->bUseServerSideRewind = false; SpawnedProjectile->Damage = Damage; SpawnedProjectile->HeadShotDamage = HeadShotDamage; } else // Server, not locally controlled - spawn non-replicated projectile, SSR { SpawnedProjectile = World->SpawnActor(ServerSideRewindProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams); SpawnedProjectile->bUseServerSideRewind = true; } } else // Client, using SSR { if (InstigatorPawn->IsLocallyControlled()) // Client, locally controlled - spawn non-replicated projectile, use SSR { SpawnedProjectile = World->SpawnActor(ServerSideRewindProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams); SpawnedProjectile->bUseServerSideRewind = true; SpawnedProjectile->TraceStart = SocketTransform.GetLocation(); SpawnedProjectile->InitialVelocity = SpawnedProjectile->GetActorForwardVector() * SpawnedProjectile->InitialSpeed; } else // Client, not locally controlled - spawn non-replicated projectile, no SSR { SpawnedProjectile = World->SpawnActor(ServerSideRewindProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams); SpawnedProjectile->bUseServerSideRewind = false; } } } else // Weapon not using SSR { if (InstigatorPawn->HasAuthority()) { SpawnedProjectile = World->SpawnActor(ProjectileClass, SocketTransform.GetLocation(), TargetRotation, SpawnParams); SpawnedProjectile->bUseServerSideRewind = false; SpawnedProjectile->Damage = Damage; SpawnedProjectile->HeadShotDamage = HeadShotDamage; } } } }