Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow setting collisions for multiple tiles at once #1322

Open
adsilcott opened this issue Jul 25, 2016 · 16 comments
Open

Allow setting collisions for multiple tiles at once #1322

adsilcott opened this issue Jul 25, 2016 · 16 comments
Labels
feature It's a feature, not a bug. usability Generally about making something more intuitive or efficient.

Comments

@adsilcott
Copy link

Often a large number of tiles on a sheet will have exactly the same collision boundaries and properties (basic walls, platforms, etc). It would save a lot of time if collisions could be applied to multiple selected tiles in the Tile Collision Editor.

This would likely include a popup to warn the user that individual tile collision assignments would be overwritten.

Alternatively, maybe the default behavior could be to "add" the new collision to to the tiles rather than overwriting them, along with an option to clear the previous assignments from the selected tiles. This could work well if the dialog displayed all of the selected tile's collisions superimposed on each other (uneditable unless they all matched). Not sure about the usefulness versus complexity of this approach.

As discussed in this issue:
#5 (comment)

@bjorn bjorn added the feature It's a feature, not a bug. label Jul 25, 2016
@bjorn
Copy link
Member

bjorn commented Jul 25, 2016

Also related to issue #1281, which suggests to move the collision editing out of a dialog and instead allow editing collision shapes of all tiles side-by-side.

The two approaches seem not entirely compatible, unless maybe we would move to a mode where all collision info is displayed side-by-side, but there is still a separate view for editing the shapes, which would modify the info on all selected tiles.

In any case, this will be something to do on the wip/tilesetdocument branch (or on master, after that branch has merged).

@adsilcott
Copy link
Author

The nice thing about the separate view approach that you mentioned, is that you could have a zoomed in view for detailed editing of the collisions, while having a zoomed out view showing you the overall tileset, which ones you've missed and which ones you are editing, and how they all fit together. I think in that way they could work well together.

Another thought: If you went with only the whole tilesheet view, then if you could create big collider objects across multiple tiles and have it split it up and assign it to all tiles that it touches individually, then if you grouped together all similar tiles on the tilesheet then you could assign them all at once, giving a similar functionality. For example put all solid tiles in one section and draw a big square across them, and group corner tiles together so you can just draw a diamond shape across all four of them, etc.

@bjorn
Copy link
Member

bjorn commented Jul 25, 2016

Another thought: If you went with only the whole tilesheet view, then if you could create big collider objects across multiple tiles and have it split it up and assign it to all tiles that it touches individually, then if you grouped together all similar tiles on the tilesheet then you could assign them all at once, giving a similar functionality. For example put all solid tiles in one section and draw a big square across them, and group corner tiles together so you can just draw a diamond shape across all four of them, etc.

It's a neat idea, but in this case the collision info should probably be stored as a single object group along with the tileset. But that doesn't work with image collection tilesets, nor would it allow collision info to be auto-adjusted when the tileset size is changed (I'm currently fixing that... #1315).

I'll try to go with the separate view for editing collision info for now.

@mwillson
Copy link

Wondering if there's been any progress on this? Didn't see anything on the Roadmap and wondering if/how I could contribute maybe?

@bjorn
Copy link
Member

bjorn commented Nov 23, 2017

@mwillson Well, at least the wip/tilesetdocument branch was eventually merged and the collision editor is now a view that is part of the tileset editor. But no progress has been made on actually allowing to edit collisions of multiple tiles at once. And indeed, the Roadmap is pretty crowded so I would be reluctant to add it to the list currently.

So, the best way to help is probably to take a stab at implementing it yourself. You're very welcome to try it and I'm available in case you have any questions.

The tileset view already allows multiple tiles to be selected at once, and all selected tiles can be obtained from the TilesetDocument, but the collision editor only deals with the single "current tile". So that is where most of the work would need to be done. Also, please write about how you'd expect the behavior to be before you start.

@mwillson
Copy link

Thanks @bjorn for pointing me in the right direction. I'll clone the repo and look through that area of the code. And I'll try and come up with a small proposal about what to do based on my ideas + what you guys have talked about in this thread already. I was looking at Unity's new tilemap editor btw and I think it would be nice to make something like what they have that uses the tile geometry to auto-create the colliders. Perhaps some solution that allows that and ALSO custom widely-applied collisions would be nice. Anyway, I'll write out something a little more formal later

@bjorn
Copy link
Member

bjorn commented Nov 24, 2017

I was looking at Unity's new tilemap editor btw and I think it would be nice to make something like what they have that uses the tile geometry to auto-create the colliders.

Isn't that exactly what Tiled2Unity is doing? If there's something that could be improved in Tiled about this feel free to open an issue with some more details.

Thanks for taking up this issue!

@mwillson
Copy link

If Tiled2Unity does this, I was unaware. I've been using it, and as far as I can tell, it only creates the Unity collider by combining the single tile collisions you've already specified in Tiled. And that's why this is an issue. Creating those 1 by 1 is a pain, especially in the many common instances when they should all be the same anyway.

@bjorn
Copy link
Member

bjorn commented Nov 25, 2017

If Tiled2Unity does this, I was unaware. I've been using it, and as far as I can tell, it only creates the Unity collider by combining the single tile collisions you've already specified in Tiled. And that's why this is an issue. Creating those 1 by 1 is a pain, especially in the many common instances when they should all be the same anyway.

You said that Unity used the tile geometry to auto-create the colliders. I haven't personally used Unity so I thought what you meant was the way Tiled2Unity creates colliders from the "geometry" specified in the tile collision editor.

But now I assume you mean that Unity analyses the tile image, and creates the collider geometry based on its transparent areas? That would certainly be a useful feature.

@mwillson
Copy link

mwillson commented Dec 5, 2017

Yes, that.s what I mean. Something to work on :)

@mwillson
Copy link

mwillson commented Dec 5, 2017

Here's what I was thinking would be easier to implement in the short term:

Example User Flow
1.Select multiple tiles in tileset view
2.Go To Collision Editor
*There would be a button in the collision editor menu bar that says something like "copy to selected tiles"
*This button would not be active unless a collision object is selected
3.Select Single Collision Object
4.Click now-active button that says "Copy to selected tiles"
5.Celebrate! Lots of unnecessary work has been avoided.

@rosshadden
Copy link

I like your short-term idea @mwillson.

bjorn pushed a commit to robinmacharg/tiled that referenced this issue Jan 28, 2020
bjorn pushed a commit to robinmacharg/tiled that referenced this issue Jan 28, 2020
bjorn pushed a commit to robinmacharg/tiled that referenced this issue Jul 21, 2020
bjorn pushed a commit to robinmacharg/tiled that referenced this issue Jul 21, 2020
bjorn added a commit that referenced this issue Jul 21, 2020
* Added context menu entries to copy the selected tile collision objects to all selected tiles
* Added action to add auto-detected collision box based on tile image

Related to issue #1322.

Co-authored-by: Thorbjørn Lindeijer <bjorn@lindeijer.nl>
@bjorn
Copy link
Member

bjorn commented Jul 21, 2020

The "short-term" solution started by @robinmacharg two years ago as #1960 has now been finished and merged to master. 🎊

image

The change also added an quick action for setting a colliding bounding box based on the image contents (ignoring transparent pixels).

For now I've decided to keep this issue open for a more intuitive long-term solution.

@bjorn bjorn added the usability Generally about making something more intuitive or efficient. label Jul 21, 2020
@Ianuarius
Copy link

Pardon, is this not in 1.4.3? I only have Duplicate and Remove in the context menu.

@bjorn
Copy link
Member

bjorn commented Mar 16, 2021

@Ianuarius Yeah, as a new feature this change went into master and will be released in Tiled 1.5 (very soon now - hopefully this week). If very soon is not soon enough, you can install the latest "snapshot" instead of 1.4.3. :-)

@eishiya
Copy link
Contributor

eishiya commented Apr 22, 2022

maybe we would move to a mode where all collision info is displayed side-by-side, but there is still a separate view for editing the shapes, which would modify the info on all selected tiles.

This is the approach I'd like to see. As cool as it seems to draw a single shape over multiple tiles, I think in practice it's just more potential for confusion. An individual collision editor would still be necessary for editing complex multi-object collisions and collisions that go outside the tile bounds, anyway.

A live-updating display of all current collisions makes it easy to see how collisions line up and which tiles have or don't have collision, while still making it very clear exactly which tile(s) you're editing.

It just leaves the question of how to tackle the fact that some of the tiles may already have other collisions, and what to do in the case of *removing collision objects. The approach OP described seems most intuitive to me. Here it is in unnecessary detail:

Scan through all the tiles when the collision editor is enabled or when the tile selection is modified with the collision editor open.

  • If the tiles are all empty, then duplicate all edits to all tiles. Keep a list of objects correspondences between tiles, so that if you add objects and then delete one, it's deleted from all the tiles. The correspondence list would be a list of object lists, where each object list contains exactly one object from each tile, these objects being the ones deemed identical matches.
    • Do not prompt the user to add or replace objects.
    • Changes to an object's properties should be duplicated to its copies in all the selected tiles.
  • If the tiles are not empty, build up a similar correspondence list, but only for objects that are exact matches (location, shape, name, type, custom properties). Put any other objects in a separate list of "unique" objects. The unique list can just be a plain list of objects, but should probably be a map of tile -> unique objects to speed up operations on it.
    • This would really be the same logic branch as the previous one, the tiles all being empty is just a special case of them having all exactly corresponding collisions :]
    • If all the tiles have exactly matching objects (i.e. the unique objects list is empty), then as before, all changes are silently propagated through all tiles, including deletions and property changes.
    • If the unique objects list is not empty, then prompt the user and give them these options before letting them edit:
      • (if correspondence list is empty) Add / Replace
        • Add: Any new objects are added to the correspondence list. Deleting it from one tile deletes from them all, etc. Existing unique objects are perhaps locked for editing. If they're not locked, then changes to them should not propagate (it's easy to discern which objects should propagate and which should not - the non-propagating objects are in the unique list).
        • Replace: Upon the first change (move, property change, add, etc), unique objects in all other tiles are deleted and the objects from the current tiles are copied in their stead. From that point on, it's just like the simple scenario of starting with all empty tiles, all objects correspond.
      • (if correspondence list is not empty) Add / Replace Unique. The options would work identically to Add/Replace, the different name just makes it clearer that matching objects will be preserved unless the user explicitly deletes them (since they're corresponding, deleting them in one tile will delete them from all selected tiles).

The actual logic should have fewer branches in it than this list suggests, I separated/duplicated some functionally identical things just to make it easier to follow. It's really just:

  • Build correspondence and unique lists when collision mode is activated or the selection is changed in collision mode
  • If unique count > 0, prompt Add/Replace, changing "Replace" name based on whether correspondence count > 0.
    • If Replace: Delete all unique objects upon first change.
  • When adding objects: Add to correspondence list, copy to all selected tiles.
  • When changing/deleting objects:
    • If object is in correspondence list: repeat change on all corresponding objects.
    • If object is in unique list, and it's not locked: Apply change to object, do not propagate. This would happen if you decide not to lock unique objects in Add mode.

Building the correspondence and unique lists would probably be a fairly heavy action, so ideally it should not be fully rebuilt every time the selection changes. Some ideas on updating this list dynamically, which would probably also work for building the initial lists:

  • Subtracting tiles from the selection should remove their objects from the lists.
    • After all the to-be-removed tiles have been removed, look for exact matches among the unique list (this is where making it a map of tile -> unique objects comes in handy!), since it's possible the deleted tiles were preventing some objects from counting as correspondences. If "unique" objects are found that match across all tiles, move them into the correspondence list.
  • Adding tiles to a non-empty selection should compare their tiles to the correspondence list.
    • Any objects matching a corresponding object get added to that list. Any others get put in the unique list.
      • To make this work correctly, adding the very first tile an empty list to should put all of its objects into the correspondence list.
    • After adding all the objects, look through the correspondence list, and if any list of correspondences doesn't include the new tile, move those objects to the unique list. It's also possible to keep a list of matched and unmatched correspondences while doing the initial adding, to avoid having to iterate it all again afterwards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature It's a feature, not a bug. usability Generally about making something more intuitive or efficient.
Projects
None yet
Development

No branches or pull requests

6 participants