@@ -1693,6 +1693,201 @@ public IEnumerator UI_CanDriveUIFromMultipleTouches()
16931693 Assert . That ( scene . leftChildReceiver . events , Is . Empty ) ;
16941694 }
16951695
1696+ // https://issuetracker.unity3d.com/product/unity/issues/guid/ISXB-845
1697+ // This tests that we can release and press touches on the same frame with the expected events and touchIds.
1698+ [ UnityTest ]
1699+ [ Category ( "UI" ) ]
1700+ public IEnumerator UI_CanReleaseAndPressTouchesOnSameFrame ( )
1701+ {
1702+ var touchScreen = InputSystem . AddDevice < Touchscreen > ( ) ;
1703+
1704+ // Prevent default selection of left object. This means that we will not have to contend with selections at all
1705+ // in this test as they are driven from UI objects and not by the input module itself.
1706+ var scene = CreateTestUI ( noFirstSelected : true ) ;
1707+
1708+ var asset = ScriptableObject . CreateInstance < InputActionAsset > ( ) ;
1709+ var map = asset . AddActionMap ( "map" ) ;
1710+ var pointAction = map . AddAction ( "point" , type : InputActionType . PassThrough , binding : "<Touchscreen>/touch*/position" ) ;
1711+ var leftClickAction = map . AddAction ( "leftClick" , type : InputActionType . PassThrough , binding : "<Touchscreen>/touch*/press" ) ;
1712+
1713+ scene . uiModule . point = InputActionReference . Create ( pointAction ) ;
1714+ scene . uiModule . leftClick = InputActionReference . Create ( leftClickAction ) ;
1715+
1716+ map . Enable ( ) ;
1717+
1718+ yield return null ;
1719+
1720+ scene . leftChildReceiver . events . Clear ( ) ;
1721+
1722+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 1 ) , Is . False ) ;
1723+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 2 ) , Is . False ) ;
1724+
1725+ // Touch left object.
1726+ var firstPosition = scene . From640x480ToScreen ( 100 , 100 ) ;
1727+ BeginTouch ( 1 , firstPosition ) ;
1728+ yield return null ;
1729+
1730+ var pointerIdTouch1 = ExtendedPointerEventData . MakePointerIdForTouch ( touchScreen . deviceId , 1 ) ;
1731+ var pointerIdTouch2 = ExtendedPointerEventData . MakePointerIdForTouch ( touchScreen . deviceId , 2 ) ;
1732+ var pointerIdTouch3 = ExtendedPointerEventData . MakePointerIdForTouch ( touchScreen . deviceId , 3 ) ;
1733+
1734+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 1 ) , Is . True ) ;
1735+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 2 ) , Is . False ) ;
1736+
1737+ Assert . That ( scene . leftChildReceiver . events ,
1738+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerEnter ) . And
1739+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1740+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 1 ) . And
1741+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch1 ) . And
1742+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1743+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == firstPosition ) ) ;
1744+ Assert . That ( scene . leftChildReceiver . events ,
1745+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerDown ) . And
1746+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1747+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 1 ) . And
1748+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch1 ) . And
1749+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1750+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == firstPosition ) ) ;
1751+
1752+ Assert . That ( scene . rightChildReceiver . events , Is . Empty ) ;
1753+ Assert . That ( scene . uiModule . m_PointerStates . length , Is . EqualTo ( 1 ) ) ;
1754+
1755+ scene . leftChildReceiver . events . Clear ( ) ;
1756+ scene . rightChildReceiver . events . Clear ( ) ;
1757+
1758+ // Release left object and Touch right object on the same frame.
1759+ var secondPosition = scene . From640x480ToScreen ( 350 , 200 ) ;
1760+ EndTouch ( 1 , firstPosition ) ;
1761+ BeginTouch ( 2 , secondPosition ) ;
1762+ BeginTouch ( 3 , secondPosition ) ;
1763+ MoveTouch ( 2 , secondPosition ) ;
1764+ yield return null ;
1765+
1766+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 1 ) , Is . True ) ;
1767+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 2 ) , Is . True ) ;
1768+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 3 ) , Is . True ) ;
1769+
1770+ // Pointer 1
1771+ Assert . That ( scene . leftChildReceiver . events ,
1772+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerUp ) . And
1773+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1774+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 1 ) . And
1775+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch1 ) . And
1776+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1777+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == firstPosition ) ) ;
1778+
1779+ // Pointer 2
1780+ Assert . That ( scene . rightChildReceiver . events ,
1781+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerEnter ) . And
1782+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1783+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 2 ) . And
1784+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch2 ) . And
1785+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1786+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1787+
1788+ Assert . That ( scene . rightChildReceiver . events ,
1789+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerDown ) . And
1790+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1791+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 2 ) . And
1792+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch2 ) . And
1793+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1794+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1795+
1796+ Assert . That ( scene . rightChildReceiver . events ,
1797+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerMove ) . And
1798+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1799+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 2 ) . And
1800+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch2 ) . And
1801+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1802+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1803+
1804+ // Pointer 3
1805+ Assert . That ( scene . rightChildReceiver . events ,
1806+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerEnter ) . And
1807+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1808+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 3 ) . And
1809+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch3 ) . And
1810+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1811+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1812+
1813+ Assert . That ( scene . rightChildReceiver . events ,
1814+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerDown ) . And
1815+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1816+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 3 ) . And
1817+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch3 ) . And
1818+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1819+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1820+
1821+ Assert . That ( scene . uiModule . m_PointerStates . length , Is . EqualTo ( 3 ) ) ;
1822+
1823+ scene . leftChildReceiver . events . Clear ( ) ;
1824+ scene . rightChildReceiver . events . Clear ( ) ;
1825+
1826+ // End second touch.
1827+ EndTouch ( 2 , secondPosition ) ;
1828+ EndTouch ( 3 , secondPosition ) ;
1829+ yield return null ;
1830+
1831+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 1 ) , Is . True ) ;
1832+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 2 ) , Is . True ) ;
1833+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 3 ) , Is . True ) ;
1834+
1835+ Assert . That ( scene . leftChildReceiver . events ,
1836+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerExit ) . And
1837+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1838+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 1 ) . And
1839+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch1 ) . And
1840+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1841+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == firstPosition ) ) ;
1842+
1843+ Assert . That ( scene . rightChildReceiver . events ,
1844+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerUp ) . And
1845+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1846+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 2 ) . And
1847+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch2 ) . And
1848+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1849+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1850+
1851+ Assert . That ( scene . rightChildReceiver . events ,
1852+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerUp ) . And
1853+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1854+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 3 ) . And
1855+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch3 ) . And
1856+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1857+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1858+
1859+ Assert . That ( scene . uiModule . m_PointerStates . length , Is . EqualTo ( 2 ) ) ;
1860+
1861+ scene . leftChildReceiver . events . Clear ( ) ;
1862+ scene . rightChildReceiver . events . Clear ( ) ;
1863+
1864+ // Next frame
1865+ yield return null ;
1866+
1867+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 1 ) , Is . False ) ;
1868+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 2 ) , Is . False ) ;
1869+ Assert . That ( scene . eventSystem . IsPointerOverGameObject ( 3 ) , Is . False ) ;
1870+
1871+ Assert . That ( scene . leftChildReceiver . events , Is . Empty ) ;
1872+ Assert . That ( scene . rightChildReceiver . events ,
1873+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerExit ) . And
1874+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1875+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 2 ) . And
1876+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch2 ) . And
1877+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1878+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1879+
1880+ Assert . That ( scene . rightChildReceiver . events ,
1881+ Has . Exactly ( 1 ) . With . Property ( "type" ) . EqualTo ( EventType . PointerExit ) . And
1882+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . device == touchScreen ) . And
1883+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . touchId == 3 ) . And
1884+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerId == pointerIdTouch3 ) . And
1885+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . pointerType == UIPointerType . Touch ) . And
1886+ . Matches ( ( UICallbackReceiver . Event e ) => e . pointerData . position == secondPosition ) ) ;
1887+
1888+ Assert . That ( scene . uiModule . m_PointerStates . length , Is . Zero ) ;
1889+ }
1890+
16961891 // https://fogbugz.unity3d.com/f/cases/1190150/
16971892 [ UnityTest ]
16981893 [ Category ( "UI" ) ]
@@ -1724,8 +1919,6 @@ public IEnumerator UI_CanUseTouchSimulationWithUI()
17241919
17251920 Assert . That ( scene . uiModule . m_CurrentPointerType , Is . EqualTo ( UIPointerType . Touch ) ) ;
17261921 Assert . That ( scene . uiModule . m_PointerIds . length , Is . EqualTo ( 1 ) ) ;
1727- Assert . That ( scene . uiModule . m_PointerTouchControls . length , Is . EqualTo ( 1 ) ) ;
1728- Assert . That ( scene . uiModule . m_PointerTouchControls [ 0 ] , Is . SameAs ( Touchscreen . current . touches [ 0 ] ) ) ;
17291922 Assert . That ( scene . leftChildReceiver . events ,
17301923 EventSequence (
17311924 AllEvents ( "pointerType" , UIPointerType . Touch ) ,
@@ -1749,8 +1942,6 @@ public IEnumerator UI_CanUseTouchSimulationWithUI()
17491942
17501943 Assert . That ( scene . uiModule . m_CurrentPointerType , Is . EqualTo ( UIPointerType . Touch ) ) ;
17511944 Assert . That ( scene . uiModule . m_PointerIds . length , Is . EqualTo ( 1 ) ) ;
1752- Assert . That ( scene . uiModule . m_PointerTouchControls . length , Is . EqualTo ( 1 ) ) ;
1753- Assert . That ( scene . uiModule . m_PointerTouchControls [ 0 ] , Is . SameAs ( Touchscreen . current . touches [ 0 ] ) ) ;
17541945 Assert . That ( scene . leftChildReceiver . events ,
17551946 EventSequence (
17561947 AllEvents ( "pointerType" , UIPointerType . Touch ) ,
@@ -1767,7 +1958,6 @@ public IEnumerator UI_CanUseTouchSimulationWithUI()
17671958
17681959 Assert . That ( scene . uiModule . m_CurrentPointerType , Is . EqualTo ( UIPointerType . None ) ) ;
17691960 Assert . That ( scene . uiModule . m_PointerIds . length , Is . Zero ) ;
1770- Assert . That ( scene . uiModule . m_PointerTouchControls . length , Is . Zero ) ;
17711961 Assert . That ( scene . leftChildReceiver . events ,
17721962 EventSequence (
17731963 AllEvents ( "pointerType" , UIPointerType . Touch ) ,
0 commit comments