Calling SpawnActor() using GetSocketLocation() does not spawn the actor at the right location

Currently trying to spawn a projectile at gun’s static mesh’s muzzle socket location. However, it has resulted in the projectile being spawned at the player character’s foot like shown here

Here’s a picture of the muzzle socket in the static mesh

And here’s the code for spawning the projectile,

for (int i = 0; i < Components.Num(); i++) {
    if (Components[i]->GetName() == "Weapon") {
        UStaticMeshComponent* WeaponComponent = Components[i];

        FVector MuzzleLocation = WeaponComponent->GetSocketLocation("muzzle");
                        
        APlayerController* PlayerController = Cast<APlayerController>(GetController());
        FRotator CameraRotation = PlayerController->PlayerCameraManager->GetCameraRotation();
        FVector CameraLocation = PlayerController->PlayerCameraManager->GetCameraLocation();
        PlayerController->GetPlayerViewPoint(CameraLocation, CameraRotation);
        FVector ShootDirection = CameraRotation.Vector();

        const FVector StartTrace = FollowCamera->GetComponentLocation();
        const FVector EndTrace = StartTrace + ShootDirection * 100000.0;
        FHitResult Impact;
        FCollisionQueryParams CollisionParams;
        GetWorld()->LineTraceSingleByChannel(Impact, StartTrace, EndTrace, ECC_Visibility, CollisionParams);

        if (Impact.bBlockingHit) {
            FTransform SpawnTransform(ShootDirection.Rotation(), MuzzleLocation);
            auto Bullet = Cast<AProjectileActor>(UGameplayStatics::BeginDeferredActorSpawnFromClass(this, CurrentWeapon->BulletClass, SpawnTransform));
            if (Bullet != nullptr)
            {
                //spawnactor has no way of passing parameters so need to use begindeferredactorspawn and finishspawningactor
                Bullet->Weapon = CurrentWeapon;
                Bullet->WeaponHolder = this;

                UGameplayStatics::FinishSpawningActor(Bullet, SpawnTransform);
            }
        }
        break;
    }
}

Not sure what’s causing this, any help would be appreciated!

EDIT
The code above is in a server rpc. Oddly enough, the bullet spawns on the muzzle socket on the server, but when replicating this back to the client the location is incorrect. I’ve also experienced a similar issue with AttachtToComponent attaching in different rotations on server vs client.

Have you tried drawing a debug sphere at the MuzzleLocation just to test if that one is correct.

that would be that

other things I see is that you don’t set the ESpawnActorCollisionHandlingMethod for BeginDeferredActorSpawnFromClass which you should set to AlwaysSpawn so that the position doesn’t get changed on spawn.

Failed to GetSocketTransform from weapon, so the Bullet spawned on ZeroVector.

+1, you should log the MuzzleLocation value ( or put breakpoint ) to check the returned value

THe weapons doesn’ tlooks like to be the same, make sure all meshes have the socket setup

I have tried doing drawdebugsphere and the bullet spawns on the socket location on the server but not on the clients. This code is currently in a server rpc. And weirdly enough it does spawn normally in a single player game. Do you think there’s a problem with spawning things server side?

Unfortunately I did try logging the muzzle location value and it’s not a zero vector. However, one thing i found out is that the bullet spawns at the socket location in a single player game but not in a multiplayer game. This code is in a server rpc currently. Do you think there’s something wrong with spawning server side? Because on the server it spawns fine but it doesn’t replicate currently to the clients.

Anyway, the code you post looks like suit only for local running. If it is in server rpc as you said, you may need to SetOwner of the bullet.

Normally, using a local function to calculate the start pose of bullet, and call a server function to spawn bullet with certain pose, would be suit for most of needs of sync-bullet. ShooterGame could be a good reference for you.

Hi Henry, sorry for the late response. It seems that SetOwner doesn’t change the result either. However, when you say use a local function to calculate the start pose, then call a server rpc to spawn the bullet, how would I pass the start pose from the local client function to the server rpc? Thanks for your help so far.

1 Like

Nevermind I’m stupid, for some reason I thought you couldn’t pass parameters to server rpcs. Calculating the location client side did work. Thank you henry.