Paper2D-Tilemap Component Generated at Runtime not Generating Collision

I posted this initially in the blueprint board, but it now seems like it could be a bug.

It seems that when the TileMapComponent is generated, there is no collision created. However, if I go into the outliner, and select the actual component in the actor that is creating the component, the collision gets created…

Note that there is no collision on the patch closest to camera (I had already selected the other patch that now has collision farthest from camera):

Components in the outliner, unselected:

93112-componentviewer.png

Selected component closest to camera:

93113-selectedcomponent.png

Collision generates:

Also, here’s the code used to create the TileMap. Note that values like “TileSet” are variables in the class. TileSet is a UPaperTileSet, and the ProcParams is a struct holding various values for producing the TileMap.

{
	// Initialize a new chunk component.
	TileMapComponent = NewObject<UPaperTileMapComponent>(GetOwner());
	{
		if (TileMapComponent && TileMapComponent->IsValidLowLevel())


		// Set the component transform and register it.
		TileMapComponent->SetRelativeLocation(ChunkCoordinates.ToFloat() * ProcMeshParams.TilesPerChunk.ToFloat() * FVector(ProcMeshParams.TileSize));
		TileMapComponent->AttachTo(this);
		TileMapComponent->RegisterComponent();

	}
    
	if (TileSet)
	{
		TileMapComponent->CreateNewTileMap(32, 32, 128, 128, 1.0, true);

		for (int32 y = 0; y < 32; y++)
		{
			for (int32 x = 0; x < 32; x++)
			{
				FPaperTileInfo LocalTileInfo;
				LocalTileInfo.TileSet = TileSet;
				LocalTileInfo.PackedTileIndex = 8;
				TileMapComponent->SetTile(x, y, 0, LocalTileInfo);
			}
		}
	}

}

Hello Brandelan,

I haven’t looked much at the issue yet so I can’t be 100% sure if this is the cause of the problem or just a coding mistake that isn’t having much of a difference, but it seems like your first if statement in the code provided above isn’t doing anything.

There aren’t any brackets for what it needs to encapsulate so it would seem that is it only affecting line #9 and ignoring #10 & #11 which seem as though they would need to be included inside of the statement too, based off the context.

Could you take a look at this and see if it may be the problem?

I put the brackets in, and it had no bearing on the problem.

That if statement was just a sanity check to make sure the TileMapComponent had been created, anyway. It was meant to stop the execution of lines 9 through 11 if the component hadn’t been properly created somehow. If it wasn’t there at all, and the component hadn’t been created, the program would simply crash when trying to execute lines 9 through 11.

As it stands, missing the brackets don’t really matter in relation to the problem.

I figured it would cause a crash if anything, but good to fix the small problems too.

Would it be possible to get a copy of this project or a sample project that has the same issue? I’m having some trouble getting the same results as you, although my overall setup outside of the spawning process could be different.

If you want to send a project, you can post a link to download it here or you can send it to me in a private message on our to keep it private.

[1]:

I PM’d you.

Thanks for looking into this! :slight_smile:

Thank you for sending me a reproduction project. I see the discrepancy now, it’s that I wasn’t using that specific component. As it says in the editor, the PaperTileMapComponent is an early access component and isn’t quite ready for use. I’ve reported this as a bug for it but I would expect it to take a while before this gets fixed due to the state of the component itself. For reference, the bug’s number is UE-31632.

Unfortunately I can’t think of a workaround that still involves using this component.

Not altogether unexpected, but still disappointing.
Thanks anyway. :slight_smile:

Hello Brandelan,

After speaking to a developer about this problem, it seems like you need to use RebuildCollision() for this collision to work. I see that you had the node for RebuildCollision in your event graph but it’s no longer part of any executed code. Could you try including this after building/initializing your SpriteMap and see if that fixes the issue?

Added the RebuildCollision() and it still doesn’t seem to work. I added it in multiple places, with no luck. Thanks for continuing to look into this. :slight_smile:

{
	// Initialize a new chunk component.
	TileMapComponent = NewObject<UPaperTileMapComponent>(GetOwner());
	{
		if (TileMapComponent && TileMapComponent->IsValidLowLevel())
		{
			// Set the component transform and register it.
			TileMapComponent->SetRelativeLocation(ChunkCoordinates.ToFloat() * TileMapParams.TilesPerChunk.ToFloat() * FVector(TileMapParams.TileSize));
			TileMapComponent->SetRelativeRotation(FRotator(0.0f, 0.0f, -90.0f));
			TileMapComponent->AttachTo(this);
			TileMapComponent->RegisterComponent();
		}

	}
						
	TileMapComponent->RebuildCollision();

	// Add the chunk to the coordinate map and visible chunk array.
	TileMapCoordinatesToComponent.Add(ChunkCoordinates, TileMapComponent);

	if (TileSet)
	{
		//this will be the key bit of code for creating the different tiles
		TileMapComponent->CreateNewTileMap(TileMapParams.TilesPerChunk.X, TileMapParams.TilesPerChunk.Y, TileMapParams.TileSize, TileMapParams.TileSize, 1.0, true);

		for (int32 y = 0; y < TileMapParams.TilesPerChunk.Y; y++)
		{
			for (int32 x = 0; x < TileMapParams.TilesPerChunk.X; x++)
			{
				FPaperTileInfo LocalTileInfo;
				LocalTileInfo.TileSet = TileSet;
				LocalTileInfo.PackedTileIndex = 8;
				TileMapComponent->SetTile(x, y, 0, LocalTileInfo);
			}
		}
	}
}

From what I understand, the RebuildCollision would need to be called after the nested for loop you’re using to creating the tiles. These are the pieces that need to generate that collision which needs to be prompted by calling RebuildCollision. Have you tried calling it after those for loops?

Hi,

Im having the same problem and i’ve been trying any solution i can think of. I tried calling RebuildCollision() after every SetTile() call, and at then end of all processes.

Also i can confirm that as you said refreshing the TileMap in the outliner creates the collision properly if started from Simulate.

Our project generates the world procedurally using the Tilemap as a canvas, so we heavily rely on this feature, even though we knew this was experimental, lets hope we get to the bottom of this and can continue!

Yeah, I tried it after those loops as well.

I just noticed that I never responded; Thank you for that information. I’ve reopened the bug report for review so I’ll be sure to let you know of any further updates or if I need any more information.

I’ve checked in a fix to Dev-Framework for this issue which will make it’s way to main shortly and be a part of 4.13 (CL# 3045344).

The issue is that the body setup was not being updated when editing the tile map via code instead of via the editor, so rebuilding the collision does nothing. If you’re comfortable making edits to the engine you can make the same change (call TileMap->UpdateBodySetup in RebuildCollision if OwnsTilemap is true) but otherwise I don’t have a workaround for you until 4.13 comes out.

Cheers,
Noland

Now that i changed that in RebuildCollision() in PaperTileMapComponent.cpp im getting:

LogPhysics:Warning: AddBoxesToRigidActor: [/Game/Maps/UEDPIE_0_Map.Map:PersistentLevel.Tilemap_30.RenderComponent.PaperTileMap_63] BoxElems[1220] invalid or has invalid transform

(One for each collision) I guess im way over my head trying to edit engine code.

If you’re unable to do it yourself, I’ll be sure to post the commit that this fix is a part of when it gets merged into our fork that is visible on Github so you can get the change directly. Keep in mind that it will include other fixes however as these commits are usually bulk commits and include all of the fixes from a particular branch from a short span of time.

Hello Canjo and Brandelan. from above has checked a fix into the engine for this but I’m not having much luck getting this to work even with his fix. Before I fail it back, I wanted to give you guys a crack at it since you’re more familiar with using this than I am. If you have a chance, can you download the Master branch from our Github repository for the engine and see if you can get your project working? Please remember that you’ll still need RebuildCollision().

So, I’m trying to get the latest commit for this, but I am pretty inexperienced with github. How exactly do I get this latest version?

It would be this particular commit: .com/EpicGames/UnrealEngine/commit/a0625fd

It’s Change 3045344 in that list of changes. If you’re not sure how to get this one particular commit, I would suggest downloading the Master branch from the branch dropdown as a whole separate engine installation. This way you’ll be able to keep any of these possibly unwanted changes away from your normal installation, as it can be unstable when not in a full release. I would also suggest making a copy of your project to test this with instead of converting the original.

I’ve tried this twice, and must be doing something wrong.

When I go to GitHub and look at the master branch source code, and navigate to the PaperTileMapComponent, I’m not seeing the TileMap->RebuildCollision() change.