How do I make characters spawned dynamically not stuck on dynamically constructed floor?

I have a character that I spawn from a dynamically created player start onto a dynamically created floor. Right now, the character cannot move across the floor normally. I can see that the movement events are firing, and the character can jump properly. This means that I can do a tiny bunny-hop to move around on the floor. It’s almost as if the friction on the floor or character capsule is infinite.

The character can move correctly on the mesh that I spawn dynamically if it is statically placed in a level from the editor. The dynamic generation only currently occurs when the map is determined to be a dynamic map and occurs in the GameMode’s PreInitializeComponents method.

I’m fairly confident that I am missing some small setting that will let the movement occur normally, but I am clearly missing it.

I would appreciate any help you could provide into why the character is stuck on the floor to get it moving on the dynamically created floor.

I am using the latest version of the engine, 4.7.5. I also tried this in 4.7.3 before 4.7.5 was released.

For your convenience, the relevant pieces of code are below.

The Player Start Spawn

void ADungeonBuilder::SpawnStart(UWorld* world, ARoom* room)
{
	FVector roomExtent = room->Boundary->GetUnscaledBoxExtent();
	//TODO: Make Random in the room

	FActorSpawnParameters spawnParameters;
	spawnParameters.Owner = this;
	spawnParameters.Instigator = Instigator;

	FVector spawnLocation(-600, -600, -600);
	FRotator spawnRotation(FRotator::ZeroRotator);

	PlayerStart = Cast<APlayerStart>(world->SpawnActor<AActor>(APlayerStart::StaticClass(), spawnLocation, spawnRotation, spawnParameters));
		
	PlayerStart->AttachRootComponentToActor(room);

	PlaceExitVolume(world, room);
}

The room tile method. (where all floor tiles are placed in the world)

void ADungeonBuilder::TileFloor(ARoom* room)
{
	UStaticMesh* floorMesh = LoadFloorMesh();
	UMaterial* floorMaterial = LoadFloorMaterial();

	FVector meshExtent = floorMesh->GetBounds().BoxExtent;
	FVector roomExtent = room->Boundary->GetUnscaledBoxExtent();

	//TODO: Handle case where room is smaller than mesh
	uint32 tilesWide = roomExtent.X / meshExtent.X;
	uint32 tilesDeep = roomExtent.Y / meshExtent.Y;

	float startX = -roomExtent.X;
	float startY = -roomExtent.Y;
	float startZ = -roomExtent.Z + meshExtent.Z;

	float slideX = meshExtent.X * 2;
	float slideY = meshExtent.Y * 2;

	for (uint32 deepRank = 0; deepRank < tilesDeep; ++deepRank)
	{
		for (uint32 wideRank = 0; wideRank < tilesWide; ++wideRank)
		{
			FVector nextCenter(startX + slideX*wideRank, 
							   startY + slideY*deepRank, 
							   startZ);
			UStaticMeshComponent* floorComponent = LoadComponent(floorMesh);

			floorComponent->SetMaterial(0, floorMaterial);
			floorComponent->SetWorldLocation(nextCenter);
			floorComponent->RegisterComponentWithWorld(GetWorld());
			floorComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);			
			floorComponent->AttachTo(room->GetRootComponent());
			room->Floor.Add(floorComponent);
		}
	}
}

The floor mesh loader

UStaticMesh* ADungeonBuilder::LoadFloorMesh()
{
	TCHAR* floorName = TEXT("/Game/Architecture/Floor_400x400.Floor_400x400");
	UStaticMesh* floorMesh = LoadObject<UStaticMesh>(NULL, floorName, NULL, LOAD_None, NULL);	
	
	return floorMesh;
}

The Component Loader

UStaticMeshComponent* ADungeonBuilder::LoadComponent(UStaticMesh* mesh)
{
	UStaticMeshComponent* floorComponent = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass());
	floorComponent->SetStaticMesh(mesh);
	floorComponent->SetMobility(EComponentMobility::Movable);
	floorComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
	floorComponent->bCanEverAffectNavigation = true;
	floorComponent->bCastDynamicShadow = true;
	
	
	return floorComponent;
}

The Material Loader

UMaterial* ADungeonBuilder::LoadFloorMaterial()
{
	TCHAR* floorMaterialName = TEXT("/Game/Materials/M_CobbleStone_Smooth.M_CobbleStone_Smooth");
	UMaterial* floorMaterial = LoadObject<UMaterial>(NULL, floorMaterialName, NULL, LOAD_None, NULL);
	
	return floorMaterial;
}

Edit: Included the engine version.

I guess since no one got the chance to answer, I have to answer my own question :(.

It appears that you need to create organize this differently than I was hoping. I got the premise to work by creating a blueprint with the parent of the StaticMeshActor, and spawning that blueprint in the TileFloor method. The ComponentLoader and the MeshLoader are not needed because of this.

I still think that there is probably a way to load the information outside the constructor of an Actor and still have valid collision, but it is not immediately obvious how to set it up. (I haven’t had the time to dig into the engine code directly, but may if this path doesn’t work the way I’d like.)