mapeditor/tiled

Do you want to work on this issue?

You can request for a bounty in order to promote it!

`Tile.objectGroup = new ObjectGroup()` does not show group in collision editor till different tile is selected #3655

cspotcode posted onGitHub

Describe the bug

When a script programmatically adds a new ObjectGroup() to a tile, then adds shapes to that tile.objectGroup, it does not appear in the Collision Editor. It can be made to appear by switching to a different tile, then back to the original tile.

If collision shapes are added in the collision editor before the workaround described above, it seems like the collision editor replaces the scripted objectGroup with a new one.

It seems like the collision editor UI is not notified about the addition of an objectGroup via scripting.

To Reproduce

Steps to reproduce the behavior:

Add the following script to a project:

const setupCollisionActionId = 'setup-collision-action';
const setupCollisionAction = tiled.registerAction(setupCollisionActionId, (a) => {
    const tileset = tiled.activeAsset;
    if(tileset.isTileset) {
        const tileset = tiled.activeAsset;
        const [tile] = tileset.selectedTiles;
        if(tile.objectGroup == null) {
            tile.objectGroup = new ObjectGroup();
        }
        const point = new MapObject('origin');
        point.shape = MapObject.Point;
        tile.objectGroup.addObject(point);
    }
});
setupCollisionAction.text = "Setup Collision";
tiled.extendMenu('TilesetView.Tiles', [{
    action: 'setup-collision-action'
}]);

Open a tileset with at least two tiles, that do not have any collision shapes in the collision editor. Select the first tile. Open the collision editor before the next step. Right-click the tile, click "Setup Collision" to run the scripted action. Observe that the collision editor does not show the new Point Click the second tile in the tileset, then click back to the first. Observe that the collision editor is now showing the new Point

Expected behavior

When scripting adds an objectGroup to a tile, it should appear immediately in the collision editor.

Media

Animation

Specifications:

  • OS: Windows 11
  • Tiled Version: 1.10.1

There seem to be a number of assignments you can do that don't trigger a refresh of the relevant displays. Another example is ImageLayer.setImage() (mentioned in a different issue). I wonder if there's some way to discover/fix these en masse.

posted by eishiya about 2 years ago

I dug into the code a bit. Looks like the Collision Editor stores a clone of the tile's objectGroup and synchronizes with the tile every time it changes collision stuff.

https://github.com/mapeditor/tiled/blob/3b2a3c47cb1c8affe59865f671663b7c6ca2e8ef/src/tiled/tilecollisiondock.cpp#L417-L421

So I think the Tile needs to emit a signal for this, and the Collision Editor needs to subscribe on that signal and re-clone the objectGroup when it changes.

I'm not sure if we'd hit failures where the user makes changes in the collision editor, but those changes do not immediately get copied to the Tile? If so, the signal would fire and the tile's objectGroup would overwrite the user's modifications in the Collision Editor.

posted by cspotcode about 2 years ago
posted by cspotcode about 2 years ago

When scripts assign to objectGroup, I assume they are triggering this method, which does not emit that event:

When script does this, it should be using ChangeTileObjectGroup, which calls mTilesetDocument->swapTileObjectGroup, which does trigger the event (as per linked code above). So there must be more to this.

posted by bjorn about 2 years ago

Fund this Issue

$0.00
Funded
Only logged in users can fund an issue

Pull requests