Download

RPC to spawn an actor creating two instances of it, and failing collision check?

Hello,

I’m trying to create a system to spawn player controlled actors (as a block or a barrel), so players can position them, and later on lock them in place.

This is the function I’m using to spawn a block:


void AHavenWeapon_BuildGun::SpawnBlock()
{
	if (GetPawnOwner()->IsCarryingBlock())
		return;

	// Zoc (2015-04-19): Check if we're running this on the server.
	if (Role < ROLE_Authority)
	{
		ServerSpawnBlock();
		return;
	}

	UWorld* const World = GetWorld();
	if (World != NULL)
	{
		FVector SpawnLocation(0, 0, 450);
		FRotator SpawnRotation(0, 0, 0);

		FActorSpawnParameters SpawnParams;
		SpawnParams.Owner = GetPawnOwner();

		ABaseBlock* ManipulatedBlock = World->SpawnActor<ABaseBlock>(GetPawnOwner()->GetNewBlockType(), SpawnLocation, SpawnRotation, SpawnParams);
		ManipulatedBlock->SetSimulatePhysics(false);
		GetPawnOwner()->SetManipulatedBlock(ManipulatedBlock);
	}
}

And there’s a function that runs on the player that checks if the placement is valid, changing the color of the actor.

Everything was working fine (or at least I thought), until I added this:



	TArray< FOverlapResult > OverlapResult; // Sweep data is stored here
	bool Collided = UHavenLib::BlockSweep(ManipulatedBlock, BlockPosition, BlockRotation, OverlapResult);

	if (Collided)
	{
		UE_LOG(LogHavenWeapon, Warning, TEXT("Role: %d"), (uint8)Role);
		for (int i = 0; i < OverlapResult.Num(); i++)
		{
			if (OverlapResult*.GetActor()->IsValidLowLevel())
			{
				UE_LOG(LogHavenWeapon, Error, TEXT("%d] Actor Blocking: %s. Is Owned by This Controller: %d"), i, *OverlapResult*.GetActor()->GetName(), IsOwnedBy(this));
				ABaseBlock* tmp = Cast<ABaseBlock>(OverlapResult*.GetActor());
				if (tmp)
				{
					UE_LOG(LogHavenWeapon, Error, TEXT("%d] Our own block: %s. Is Owned by This Controller: %d"), i, *ManipulatedBlock->GetName(), IsOwnedBy(this));
				}
			}
			else
			{
				UE_LOG(LogHavenWeapon, Error, TEXT("%d] Something is blocking (NOT an actor!)."), i);
			}
		}
		// Set our model color to obstructed visual cue
	}
	else
	{
		// Set our model color to non-obstructed visual cue
		UE_LOG(LogHavenWeapon, Warning, TEXT("No Collision"));
	}


UHavenLib::BlockSweep is a call to GetWorld()->ComponentOverlapMultiByChannel(), just a shortcut to save time when calling it (without needing to setup a bunch of stuff).

The odd part is, as soon as a block is created with the SpawnBlock() function, it changes the skin to “obstructed mode” and I get this:


LogHavenWeapon:Warning: Role: 3
LogHavenWeapon:Error: [0] Actor Blocking: BP_Block2x3_C_375. Is Owned by This Controller: 1
LogHavenWeapon:Error: [0] Our own block: BP_Block2x3_C_374. Is Owned by This Controller: 1

The instance with the lowest number (in this cast 375) appears in UE4 Editor, if I inspect the elements in “World Outlines”, but… After a while, the one with the higher number (in this case, 375) disappear, setting the skin back to the “un-obstructed mode”. Also, this is something that doesn’t always happen (sometimes it just sits there, “obstructed”).

What I imagine that is happening is: there’s the server version and the client version of the actor and the ComponentOverlapMultiByChannel() function is colliding them.
I’m currently searching for a way to show the game that these two instances (374 and 375) are the same actor, but no success yet :frowning:

I’ve been searching for a solution for a while, can you guys give me a help and/or ideas on what should I investigate?

Thank you in advance! :slight_smile:

Update:

I updated the function SpawnBlock() with:


		GEngine->AddOnScreenDebugMessage(-1, 5.f, FColor::Yellow, FString::Printf(TEXT("Positioning New Block (%s). Player Team: %d"), *ManipulatedBlock->GetName(), (uint8)(Cast<AHavenPlayerState>(GetPawnOwner()->PlayerState)->GetTeam())));


After the block spawn and it was showing me one actor was being spawned.

Then I replaced:


	if (Role < ROLE_Authority)
	{
		ServerSpawnBlock();
		return;
	}

with


	if (Role == ROLE_AutonomousProxy)
	{
		ServerSpawnBlock();
		return;
	}

and I receive the message that two entities are spawned… But not sure why :confused:

bump, since this was buried
No success yet… Is there any recommended way of checking if the actor on client and server are supposed to be the same?
I’m considering adding a player based array with network replication and check there.

In source engine, we used to have macros (#ifdef CLIENT_DLL) to check if we’re in client side code or server side code. Is there anything Close to that in ue4? This would help me tracking down the problem.

Thank you again in advance.