UGTK cat mascotUGTKengine within an engine Request access

UGTK / Toolkit / Gameplay Systems / Tangram System Completed

Gameplay Systems — UGTK

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

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

  1. Open TangramScene - note it sits at the root of the module, not under Debug/.
  2. Place TangramGrid, which holds Mn_TangramGrid and defines the board the pieces snap to.
  3. Add the pieces from Prefabs/TangramElements/: TangramElement_1x1, _2x1, _3x2 and _L. Each is a Mn_TangramElement built out of TangramPart cells.
  4. TangramTile is a single cell of the board; S_TilesCombination describes which cells a piece occupies, which is what the grid compares against when deciding whether a drop is valid.
  5. RotateOnClick gives a piece its rotation, and Mn_MoveToAveragePosition re-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

  1. Build the board from the provided prefabs: TangramGrid (with Mn_TangramGrid) holding child TangramTiles, and the TangramElement_* piece prefabs (each an Mn_TangramElement with Mn_TangramPart children).
  2. On the grid, fill tilesCombinations with S_TilesCombination entries: the list of Mn_TangramTiles that make up a solution plus the identifier of the piece that must occupy them.
  3. Give each Mn_TangramElement a matching identifier; drag pieces so their parts collide with tiles (parts call AddTile / RemoveTile), then call TryToSnap() to snap onto free tiles and ReleaseTiles() to detach.
  4. Every frame Mn_TangramGrid checks each combination; when all its tiles hold the same element with the matching identifier it locks them and invokes that element's onPositionedCorrectlyEvent.
  5. Subscribe to onAllTilesOccupied on the grid to detect puzzle completion; per-piece feedback is available via onSnapEvent / 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:

  1. Drag a piece onto its slot and let it snap.
  2. Release one just outside the tolerance.
  3. Place a piece by hand in the Scene view, then press TryToSnap() from the inspector.
  4. 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


© 2026 Marcello De Bonis. All rights reserved

Real dependenciesOpen in the map →

Measured from the repository: code references (asmdef) plus prefab and asset GUIDs. Importing this module alone brings in 15 modules in total.