Download

C++ code not working, but same algorithm in Blueprints works?

So I’m spawning default weapons for characters and Basicly the algorithm is this:

  1. In BeginPlay() run a timer for one second (which will ensure that all players are initialized already) and that timer set to run a function EventSpawnWeapons()

which is basicly this:


void ABaseHero::EventSpawnDefaultWeapons()
{
	//GEngine->AddOnScreenDebugMessage(4, 2.0f, FColor::Red, TEXT("Gonna spawn weapons here!"));

	GetWorldTimerManager().ClearTimer(SpawnInventoryTimerHandle);

	//APlayerController* PlayerController = GetWorld()->GetFirstPlayerController();
	APlayerController* PlayerController = UGameplayStatics::GetPlayerController(GetWorld(), 0);

	if (HasAuthority())
	{
		SpawnDefaultWeapons(PlayerController);
	}
	else
	{
		ServerSpawnDefaultWeapons(PlayerController);
	}
}

  1. After I check if it’s a server or client, I run SpawnDefaultWeapons() or ServerSpawnDefaultWeapons() where the server function is marked as [Server, Reliable, WithValidation] and basicly in the _Implementation() I call the SpawnDefaultWeapons()

And the SpawnDefaultWeapons() is:


void ABaseHero::SpawnDefaultWeapons(APlayerController* PlayerController)
{
	if (PlayerController)
	{
		//cast to basehero
		ABaseHero* Hero = Cast<ABaseHero>(PlayerController->GetPawn());
	
		if (Hero)
		{
			//get transform
			FTransform Transform = Hero->GetActorTransform();

			//spawn
			FActorSpawnParameters Params;
			Params.Instigator = nullptr;
			Params.Owner = nullptr;
			
			AWeapon* WeaponTemp = GetWorld()->SpawnActor<AWeapon>(DefaultPrimaryWeapon, Transform, Params);
			//until here, everything is fine, and works
			if (WeaponTemp)
			{
				//after the gun is spawned multicast it's setup to all clients
				MulticastWeaponSetup(WeaponTemp, Hero);
			}
		}
	}
}

and as you can see by the comments, spawing is fine and then I do a multicast event to setup the weapon. The multicast function is marked as [NetMulticast, Unreliable, WithValidation] and it’s code is:


void ABaseHero::MulticastWeaponSetup_Implementation(AWeapon* Weapon, ABaseHero* Character)
{
	if (Weapon && Character)
	{
		//put it in inventory
		Character->Inventory->PrimaryWeaponSlot = Weapon;

		//these both don't work, only the last attach works

		//set the owner
		Character->Inventory->PrimaryWeaponSlot->SetOwner(Character);

		//attach to hands
		FAttachmentTransformRules AttachRules = FAttachmentTransformRules(EAttachmentRule::SnapToTarget, false);
		Weapon->AttachToComponent(Character->GetMesh(), AttachRules, TEXT("GunSocket"));
	}

}

And after I run the game, the server spawns a weapon, and sets the owner and puts it in nvetory and I can shoot. But for the client, it only spawns the weapon and attaches it to the hands, while it does not set it’s owner or put it in the inventory.

Absolutely the same algorithm applied to Blueprints is working just fine. I ensured all pointers are valid, Double checked everything, ran the debugger, tried whatnot. It doesn’t want to work. Been struggling for 4 days until I gave up and wanted to ask here.

Anyone any ideas?

maybe inventory needs replication?

What do you mean, need replication? The actual property in Character class or the actual properties of the UInventory class?

By the way, what is the difference between marking it as replicated or making a server function to change it?

Edit. I tried making it replicated but it still doesn’t work.