UGTK / Toolkit / Gameplay Systems / Tangram System Completed
Tangram System
Summary
The Tangram System is a drag-and-drop tangram puzzle: multi-cell pieces (Mn_TangramElement, made of Mn_TangramPart children) snap onto a grid of Mn_TangramTile. The grid validates tile combinations by identifier, locks correctly placed pieces, and fires an event when all required tiles are occupied.
Content
Modules Dependencies
- Utility Systems / Copy Paste System:
Mn_TangramElement.identifierandS_TilesCombination.identifieruse the[CopyPaste]attribute.
Carried inside the prefabs. These modules are not referenced by the assembly definition - the components are simply already attached to the prefabs this module ships. Remove one of them from the project and the prefab keeps its layout and loses that behaviour, with nothing in the console to say so.
| Module | Component, and the prefab carrying it |
|---|---|
ComponentModule/DragDropSystem |
Mn_DragDropComponent (in TangramElement_1x1), Mn_DragDropComponent (in TangramElement_2x1), Mn_DragDropComponent (in TangramElement_3x2), and 1 more |
ComponentModule/FollowSystem |
Mn_MouseFollowComponent (in TangramElement_1x1), Mn_MouseFollowComponent (in TangramElement_2x1), Mn_MouseFollowComponent (in TangramElement_3x2), and 1 more |
DesignPattern/StateMachine |
Mn_State (in TangramElement_1x1), Mn_State (in TangramElement_2x1), Mn_State (in TangramElement_3x2), and 5 more |
UtilitySystems/ActivationSystem |
Mn_GameObjectActivation (in TangramElement_1x1), Mn_GameObjectActivation (in TangramElement_2x1), Mn_GameObjectActivation (in TangramElement_3x2), and 1 more |
UtilitySystems/CollisionSystem |
Mn_ColliderMouse (in TangramElement_1x1), Mn_ColliderMouse (in TangramElement_2x1), Mn_ColliderMouse (in TangramElement_3x2), and 1 more |
UtilitySystems/EventSystem |
Mn_ZeroParametersController (in TangramElement_1x1), Mn_ZeroParametersController (in TangramElement_2x1), Mn_ZeroParametersController (in TangramElement_3x2), and 1 more |
UtilitySystems/PoolingSystem |
Mn_Pooler (in TangramElement_1x1), Mn_Pooler (in TangramElement_2x1), Mn_Pooler (in TangramElement_3x2), and 1 more |
Setup
- Open
TangramScene- note it sits at the root of the module, not underDebug/. - Place
TangramGrid, which holdsMn_TangramGridand defines the board the pieces snap to. - Add the pieces from
Prefabs/TangramElements/:TangramElement_1x1,_2x1,_3x2and_L. Each is aMn_TangramElementbuilt out ofTangramPartcells. TangramTileis a single cell of the board;S_TilesCombinationdescribes which cells a piece occupies, which is what the grid compares against when deciding whether a drop is valid.RotateOnClickgives a piece its rotation, andMn_MoveToAveragePositionre-centres a piece on the cells it covers so it lands aligned rather than where the finger was.
The snap tolerance is the whole feel of the puzzle. Too tight and correct placements bounce off,
which players read as the game being broken rather than themselves being imprecise; too loose and
the figure solves itself. Set it with the inspector's TryToSnap() on a piece you positioned by
hand, so the answer is a number rather than an impression.
How To Use
- Build the board from the provided prefabs:
TangramGrid(withMn_TangramGrid) holding childTangramTiles, and theTangramElement_*piece prefabs (each anMn_TangramElementwithMn_TangramPartchildren). - On the grid, fill
tilesCombinationswithS_TilesCombinationentries: the list ofMn_TangramTiles that make up a solution plus theidentifierof the piece that must occupy them. - Give each
Mn_TangramElementa matchingidentifier; drag pieces so their parts collide with tiles (parts callAddTile/RemoveTile), then callTryToSnap()to snap onto free tiles andReleaseTiles()to detach. - Every frame
Mn_TangramGridchecks each combination; when all its tiles hold the same element with the matching identifier it locks them and invokes that element'sonPositionedCorrectlyEvent. - Subscribe to
onAllTilesOccupiedon the grid to detect puzzle completion; per-piece feedback is available viaonSnapEvent/onTakeEvent.
Testing Scene
Open TangramScene, which sits in the root of the module - this is the one system whose test scene is not under Debug/.
What to do, in order:
- Drag a piece onto its slot and let it snap.
- Release one just outside the tolerance.
- Place a piece by hand in the Scene view, then press TryToSnap() from the inspector.
- Complete the whole figure.
Step 3 answers precisely the question dragging only hints at: would it have snapped from here? A tolerance set slightly too tight makes the puzzle feel broken rather than difficult, and that is a judgement worth making with a number rather than a feeling.
The recording is step 1 three times over: pick a piece out of the tray on the right, drag it near its slot, let go, and it lands on the grid. The green block covers three columns by two rows, the red one a single row, and each keeps the shape it had in the tray - which is the point of the tolerance in step 2, since a piece that snaps from too far away places itself for the player.
Technical Info
- Mn_TangramGrid: collects tiles, tracks occupied tiles, validates
S_TilesCombinations, locks solved pieces and raisesonAllTilesOccupied. - Mn_TangramElement: a draggable piece; manages the tiles it overlaps, performs
TryToSnap/ReleaseTiles, brings itself to front and exposes snap/take/positioned events. - Mn_TangramTile: a single grid cell (occupied / permanently locked state, assigned element).
- Mn_TangramPart: a single cell of a piece, reporting the tile it overlaps.
- Mn_MoveToAveragePosition: aligns a snapped piece onto its target tiles.
- S_TilesCombination: serializable solution (tile list + identifier).
- RotateOnClick / FrontUi: piece rotation input and bring-to-front UI helper.
© 2026 Marcello De Bonis. All rights reserved
Depends on 9
Used by 0
- No other module depends on it.
Measured from the repository: code references (asmdef) plus prefab and asset GUIDs. Importing this module alone brings in 15 modules in total.
UGTKengine within an engine


