Touch
Implementation guide for handling touch contacts in your game.
New to Board’s touch system? Read Touch first to understand how Board handles unlimited contacts, noise rejection, and Piece recognition.
Getting Active Contacts
Access current contacts through BoardInput.GetActiveContacts():
using Board.Input;
void Update()
{
// Get all active contacts (fingers and Pieces)
var contacts = BoardInput.GetActiveContacts();
foreach (var contact in contacts)
{
ProcessContact(contact);
}
}
Filtering by Type
Filter contacts by type to handle fingers and Pieces separately:
// Only finger touches
var fingers = BoardInput.GetActiveContacts(BoardContactType.Finger);
// Only Pieces
var pieces = BoardInput.GetActiveContacts(BoardContactType.Glyph);
// Both (explicit)
var all = BoardInput.GetActiveContacts(BoardContactType.Finger, BoardContactType.Glyph);
Checking if a Contact is Active
// Check if a specific contact is still active
bool isActive = false;
foreach (var c in BoardInput.GetActiveContacts())
{
if (c.contactId == savedContactId) { isActive = true; break; }
}
Contact Properties
Each BoardContact provides:
| Property | Type | Description |
|---|---|---|
contactId |
int |
Unique identifier for this contact session |
type |
BoardContactType |
Finger or Glyph |
screenPosition |
Vector2 |
Position in screen coordinates (pixels) |
previousScreenPosition |
Vector2 |
Position in the previous frame |
orientation |
float |
Rotation in radians counter-clockwise from vertical (Pieces only) |
previousOrientation |
float |
Rotation in the previous frame |
phase |
BoardContactPhase |
Current contact phase |
isTouched |
bool |
Whether a finger is touching the Piece (always true for Finger contacts) |
glyphId |
int |
Which Piece from the set (Pieces only) |
timestamp |
double |
Time when this contact was last updated |
isInProgress |
bool |
Whether the contact is currently active (not ended or canceled) |
Position
Screen position is in pixel coordinates matching the display resolution (1920×1080):
Vector2 position = contact.screenPosition;
// Convert to world position (for 2D games)
Vector3 worldPos = Camera.main.ScreenToWorldPoint(
new Vector3(position.x, position.y, 10f)
);
Orientation
Piece rotation in radians counter-clockwise from vertical:
float rotation = contact.orientation;
// Apply to a transform (convert radians to degrees for Euler)
transform.rotation = Quaternion.Euler(0, 0, rotation * Mathf.Rad2Deg);
Delta Values
Calculate movement and rotation between frames:
Vector2 deltaPosition = contact.screenPosition - contact.previousScreenPosition;
float deltaRotation = contact.orientation - contact.previousOrientation;
Contact Phases
Contact phases indicate the lifecycle of a touch or Piece placement:
| Phase | Description |
|---|---|
Began |
Contact started this frame |
Moved |
Contact position or rotation changed |
Stationary |
Contact is active but unchanged |
Ended |
Contact ended normally (lifted) |
Canceled |
Contact ended abnormally (e.g., pause screen opened) |
Note: When the pause screen opens, all active contacts are canceled. Your game should handle this by cleaning up any contact-related state when receiving
Canceledphases.
Handling Phases
void ProcessContact(BoardContact contact)
{
switch (contact.phase)
{
case BoardContactPhase.Began:
// Create visual representation, start tracking
SpawnContactVisual(contact);
break;
case BoardContactPhase.Moved:
// Update position/rotation
UpdateContactVisual(contact);
break;
case BoardContactPhase.Stationary:
// Contact unchanged, may still need processing
break;
case BoardContactPhase.Ended:
case BoardContactPhase.Canceled:
// Clean up
RemoveContactVisual(contact);
break;
}
}
Phase Helper Methods
// True for Began, Moved, or Stationary
bool isActive = contact.phase.IsActive();
// True for Ended or Canceled
bool isFinished = contact.phase.IsEndedOrCanceled();
// Alternative property
bool isInProgress = contact.isInProgress;
Piece Touch State
Pieces report whether a finger is touching them:
if (contact.type == BoardContactType.Glyph)
{
if (contact.isTouched)
{
// Player is holding the Piece
HighlightPiece(contact);
}
else
{
// Piece is on Board but not being touched
ShowIdleState(contact);
}
}
This enables interactions like:
- Highlighting Pieces when picked up
- Different behavior for touched vs. resting Pieces
- Detecting when a player releases a Piece
Glyph IDs
For Piece contacts, glyphId identifies which Piece from the set:
if (contact.type == BoardContactType.Glyph)
{
int pieceType = contact.glyphId;
// Map to game objects
switch (pieceType)
{
case 0: SpawnWarrior(contact); break;
case 1: SpawnMage(contact); break;
case 2: SpawnArcher(contact); break;
// ... etc
}
}
Note: Glyph IDs are indices (0 to N-1) within your Piece Set. To determine which ID corresponds to which physical Piece, place each Piece on Board one at a time and log the glyph ID.
Input Settings
Configure tracking behavior through BoardInputSettings:
| Setting | Default | Description |
|---|---|---|
| Translation Smoothing | 0.5 | Smooths position updates. 0 = raw values, 1 = maximum smoothing. Lower values improve responsiveness; higher values reduce jitter. |
| Rotation Smoothing | 0.5 | Smooths orientation updates. Same range as translation smoothing. Higher values help with rotational jitter. |
| Persistence | 4 | How many frames a Piece remains tracked after losing detection. Higher values keep Pieces “alive” during brief detection gaps. Finger contacts die immediately when detection is lost. |
Changing Settings at Runtime
// Load a different settings asset
BoardInput.settings = myAlternateSettings;
// Note: This cancels all active contacts
Access the settings through BoardInput.settings.
Note: If the new settings use a different
pieceSetModelFilename(Piece Set), there will be a brief delay while the new model loads. Touch input is unavailable during this time. Plan model switches during transitions (e.g., loading screens) rather than mid-gameplay.
Multiple Input Settings
You can create multiple BoardInputSettings assets for different configurations (e.g., different Piece Sets or smoothing values).
Creating Additional Settings Assets
From Project Settings:
- Open Edit > Project Settings > Board > Input Settings
- Click the dropdown at the top showing the current settings asset
- Select New Settings Asset… to create a new one
Manually:
- Right-click in the Project window
- Select Create > Board > Input Settings
- Configure the new asset
Note:
BoardInputSettingsproperties (smoothing, persistence) are readonly at runtime. To use different values, create separate settings assets and switch between them.
Runtime Settings Switching
When you assign a different BoardInputSettings to BoardInput.settings:
- All active contacts are immediately canceled — any Pieces or fingers being tracked receive a
Canceledphase and must be re-detected - Assigning the same object reference is a no-op — the setter returns early if the settings haven’t changed
// Load a different settings asset
var alternateSettings = Resources.Load<BoardInputSettings>("AlternateBoardInputSettings");
BoardInput.settings = alternateSettings;
The Piece Set Model determines whether there’s an additional delay:
| Scenario | Behavior |
|---|---|
| Same model, different parameters | Contacts reset, new parameters apply immediately (~1-10ms) |
| Different model | Contacts reset, model loads (~500ms-1s delay during which no touches are detected) |
This means if you have multiple settings assets that share the same Piece Set Model (but differ in smoothing/persistence), switching between them is fast. Only changing the model file incurs the loading delay.
Downloading models for multiple settings:
When downloading a model through Project Settings, it’s applied to the currently selected BoardInputSettings asset. Use the dropdown at the top of Input Settings to switch between assets before downloading.
Debug Overlay UI
Visualize contacts during development using BoardInput.enableDebugView:
// Enable the overlay
BoardInput.enableDebugView = true;
// Check current state
if (BoardInput.enableDebugView)
{
// Overlay is active
}
The overlay displays:
- Contact position and orientation
- Contact ID and glyph ID
- Touch state indicator
- Contact type (finger vs. Piece)
Note: The debug overlay only works in Development builds. Enable Development Build in Build Settings.
When to Use
- Verifying Piece detection accuracy
- Debugging position/rotation tracking
- Testing touch responsiveness
- Diagnosing false positive contacts
UI Input
Add BoardUIInputModule to your EventSystem GameObjects. Use Board > Input > Add BoardUIInputModule to EventSystems for quick setup, or add the component manually.
BoardUIInputModule and InputSystemUIInputModule can coexist: in the Editor, BoardUIInputModule receives no input (no hardware), so InputSystemUIInputModule handles mouse and keyboard normally.
See Setup Reference for full configuration details.
UIToolkit Pointer Limit
When using UIToolkit (UI Toolkit / UI Elements), Unity imposes a 32-pointer limit on simultaneous input events. This is a Unity platform limitation, not a Board limitation.
The SDK handles this automatically:
- The first 32 contacts work normally
- Additional contacts beyond the limit are held in a queue
- When an existing contact ends or is canceled, queued contacts immediately receive their
Beganevent - No active contacts are interrupted or repositioned—existing interactions are always preserved
This behavior ensures smooth UX even when many fingers and Pieces are on Board simultaneously. In most games, you’ll never encounter this limit.
Note: This limit only affects UIToolkit. If you’re using uGUI (Canvas-based UI) or handling input directly through
BoardInput, there is no pointer limit.