My game has a variable amount of vertically placed sectors (fields), each of which contains a cursor that moves up and down along a bar when the player touches within a given field.
The sectors are defined by Rect variables in another part of the code, but I'm just putting what's in Update() here.
I had a hard time finding a way to assign the Touches by fingerId to a cursor. Before, I tried GetInput.Touch(touchIds[i]) but there was something like a timing discrepency between the TouchPhase.Ended and the unavailability of the same Touch that was causing NullReference errors. Using t for everything within foreach() and checking the fingerId with an if() works, though it all looks a bit monstrous.
if (Application.isMobilePlatform)
{
if (Input.touchCount > 0)
{
foreach (Touch t in Input.touches)
{
if (t.fingerId < cursorAmount) //limit amount of usable touches to amount of cursors
{
if (t.phase == TouchPhase.Began)
{
Vector2 touchPos = new Vector3
(t.position.x,
Screen.height - t.position.y //adjust for Rect-dimensions, where 0 is at top of screen
);
int i = 0;
while (i < sectors.Length)
{
if (sectors[i].Contains(touchPos) && !cursorIsAssignedTouch[i])
//check if current touch (i) is in one of the Rect-sectors
//check if current touch is already assigned
{
touchIds[i] = t.fingerId; //assign touch to ID by saving this touch's ID in array whose numbering corresponds to cursors' array
cursorIsAssignedTouch[i] = true; //save whether cursor has been assigned or not
break; //stop checking
}
i++;
}
}
for (int i = 0; i < cursorAmount; i++)
{
if (t.phase == TouchPhase.Ended || t.phase == TouchPhase.Canceled)
{
if (cursorIsAssignedTouch[i] && t.fingerId == touchIds[i])
//check whether current t is the assignment of i (and whether i is assigned at all- otherwise, old ID
//of no-longer-active touch could be used
{
cursorIsAssignedTouch[i] = false; //cursor is no longer assigned after phase ends
if (ap[i].paramStat == ParamStat.cursorMain)
//if value is set to 'cursorMain', reset cursor position @ phaseEnd
{
Vector3 pos = new Vector3
(0f,
-orthSize,
0f);
cursors[i].localPosition = pos;
}
}
}
if (t.fingerId == touchIds[i] && cursorIsAssignedTouch[i] && (t.phase == TouchPhase.Moved || t.phase == TouchPhase.Stationary))
//as above for Ended/Canceled
{
Vector3 p = new Vector3
(0f,
Mathf.Clamp(t.position.y, clamps[i].y, clamps[i].x), //not literally x and y; clamp values within Rect.
0f);
Vector3 pos = Camera.main.ScreenToWorldPoint(p);
cursors[i].position = new Vector3
(0f,
pos.y,
0f);
}
}
}
}
}
}