public IEnumerator TestDisabledPointerCache() { TestButtonUtilities.InstantiateDefaultButton(TestButtonUtilities.DefaultButtonType.DefaultPushButton, out Interactable interactable, out Transform translateTargetObject); Vector3 targetStartPosition = translateTargetObject.localPosition; // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); PlayModeTestUtilities.GetInputSimulationService().EnablePointerCache = false; var rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(Vector3.right)); var rightPokePointer = PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right); Assert.IsNotNull(rightPokePointer); Assert.IsFalse(rightPokePointer.DestroyOnSourceLost); yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject)); Assert.IsTrue(wasClicked); Assert.IsTrue(rightPokePointer == null); Assert.IsNull(PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right)); wasClicked = false; yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject)); Assert.IsTrue(wasClicked); }
public IEnumerator TestDisableOnClick() { TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultPushButton, out Interactable interactable, out Transform innerCylinderTransform); Assert.True(interactable.IsEnabled); // OnClick, set Interactable IsEnabled false or aka disabled interactable.OnClick.AddListener(() => { interactable.IsEnabled = false; }); // Get start position of the inner cylinder before button is pressed Vector3 innerCylinderStartPosition = innerCylinderTransform.localPosition; yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, innerCylinderStartPosition, innerCylinderTransform)); Assert.False(interactable.IsEnabled, "Interactable should be disabled"); // Re-enable Interactable interactable.IsEnabled = true; yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); // Make sure the button depth is back at the starting position when re-enable the gameObject and states have reset Assert.True(innerCylinderTransform.localPosition == innerCylinderStartPosition); Assert.False(interactable.HasFocus, "Interactable has focus"); Assert.True(interactable.IsVisited, "Interactable was not visited"); GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestVoiceInputOnPrefab() { TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultPushButton, out Interactable interactable, out Transform translateTargetObject); // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); Vector3 targetStartPosition = translateTargetObject.localPosition; // Set up its voice command interactable.VoiceCommand = "Select"; interactable.VoiceRequiresFocus = false; // Find an input source to associate with the input event (doesn't matter which one) IMixedRealityInputSource defaultInputSource = CoreServices.InputSystem.DetectedInputSources.FirstOrDefault(); Assert.NotNull(defaultInputSource, "At least one input source must be present for this test to work."); // // Test speech when disabled // interactable.IsEnabled = false; yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); yield return(TestInputUtilities.ExecuteSpeechCommand(interactable.VoiceCommand, interactable.InputAction, defaultInputSource)); yield return(TestButtonUtilities.CheckButtonTranslation(targetStartPosition, translateTargetObject, false)); Assert.False(wasClicked, "Interactable was clicked."); Assert.False(interactable.IsVisited, "Interactable was visited."); // // Test speech when enabled // interactable.IsEnabled = true; yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); yield return(TestInputUtilities.ExecuteSpeechCommand(interactable.VoiceCommand, interactable.InputAction, defaultInputSource)); yield return(TestButtonUtilities.CheckButtonTranslation(targetStartPosition, translateTargetObject)); Assert.True(wasClicked, "Interactable was not clicked."); Assert.True(interactable.IsVisited, "Interactable was not visited."); GameObject.Destroy(interactable.gameObject); }
private IEnumerator RunGlobalClick(IMixedRealityInputSource defaultInputSource, MixedRealityInputAction inputAction, Vector3 targetStartPosition, Transform translateTargetObject, bool shouldTranslate = true) { yield return(TestInputUtilities.ExecuteGlobalClick(defaultInputSource, inputAction, () => { return TestButtonUtilities.CheckButtonTranslation(targetStartPosition, translateTargetObject, shouldTranslate); })); // Wait for at button release animation to finish yield return(new WaitForSeconds(TestButtonUtilities.ButtonReleaseAnimationDelay)); }
public IEnumerator TestTouchInput() { TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultPushButton, out Interactable interactable, out Transform translateTargetObject); interactable.gameObject.AddComponent <NearInteractionTouchableVolume>(); // // Test touch when disabled // interactable.IsEnabled = false; yield return(TestButtonUtilities.MoveHandToButton(interactable.transform)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.False(interactable.HasPhysicalTouch); Assert.False(interactable.HasPress); yield return(TestButtonUtilities.MoveHandAwayFromButton(interactable.transform)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); // // Test touch when enabled // interactable.IsEnabled = true; yield return(TestButtonUtilities.MoveHandToButton(interactable.transform)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasPhysicalTouch); Assert.True(interactable.HasPress); yield return(TestButtonUtilities.MoveHandAwayFromButton(interactable.transform)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.False(interactable.HasPhysicalTouch); Assert.False(interactable.HasPress); GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestSelectGlobalInput() { TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultPushButton, out Interactable interactable, out Transform translateTargetObject); interactable.transform.position = new Vector3(10f, 0.0f, 0.5f); // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); // Set interactable to global and disabled interactable.IsEnabled = false; interactable.IsGlobal = true; Vector3 targetStartPosition = translateTargetObject.localPosition; yield return(null); // Find an input source to associate with the input event (doesn't matter which one) IMixedRealityInputSource defaultInputSource = CoreServices.InputSystem.DetectedInputSources.FirstOrDefault(); Assert.NotNull(defaultInputSource, "At least one input source must be present for this test to work."); yield return(RunGlobalClick(defaultInputSource, interactable.InputAction, targetStartPosition, translateTargetObject, false)); Assert.False(wasClicked, "Interactable was not clicked."); Assert.False(interactable.HasFocus, "Interactable had focus"); Assert.False(interactable.IsVisited, "Interactable was not visited"); interactable.IsEnabled = true; yield return(RunGlobalClick(defaultInputSource, interactable.InputAction, targetStartPosition, translateTargetObject)); Assert.True(wasClicked, "Interactable was not clicked."); Assert.False(interactable.HasFocus, "Interactable had focus"); Assert.True(interactable.IsVisited, "Interactable was not visited"); // Unregister global handlers interactable.IsGlobal = false; // Remove as global listener and cleanup GameObject.Destroy(interactable.gameObject); }
/// <summary> /// Generates an InteractableToggleCollection from radial prefabs /// </summary> private void AssembleInteractableToggleCollection(out InteractableToggleCollection interactableToggleCollection, int numRadials, Vector3 pos) { GameObject toggleCollection = new GameObject("ToggleCollection"); interactableToggleCollection = toggleCollection.AddComponent <InteractableToggleCollection>(); // Instantiate radial prefabs with toggleCollection as the parent for (int i = 0; i < numRadials; i++) { var radial = TestButtonUtilities.InstantiateInteractableFromPath(pos + new Vector3(0.1f, i * 0.1f, 0), Quaternion.identity, RadialPrefabAssetPath); radial.name = "Radial " + i; Assert.IsNotNull(radial); radial.transform.parent = toggleCollection.transform; } interactableToggleCollection.ToggleList = toggleCollection.GetComponentsInChildren <Interactable>(); }
public IEnumerator TestPressableToggleHoloLens2() { var rightHand = new TestHand(Handedness.Right); Vector3 p2 = new Vector3(0.015f, 0f, 0.3f); TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultHL2ToggleButton, out Interactable interactable, out Transform frontPlateTransform); Assert.True(interactable.IsEnabled); interactable.transform.position = new Vector3(0.0f, 0.1f, 0.4f); bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); // Get start position of the front plate before button is pressed Vector3 frontPlateStartPosition = frontPlateTransform.localPosition; yield return(rightHand.Show(p2)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.IsTrue(interactable.HasFocus, "Interactable does not have focus when hand is pointing at it."); int numClicks = 3; for (int i = 0; i < numClicks; i++) { wasClicked = false; yield return(rightHand.Click()); // Wait for button animation to complete yield return(new WaitForSeconds(0.33f)); Assert.True(wasClicked, "Toggle button was not clicked"); Assert.AreEqual((i + 1) % 2, interactable.CurrentDimension, $"Toggle button is in incorrect toggle state on click {i}"); // Make sure the button depth is back at the starting position Assert.True(frontPlateTransform.localPosition == frontPlateStartPosition, "Toggle button front plate did not return to starting position."); } GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestForceInitialize() { Object checkboxesPrefab = AssetDatabase.LoadAssetAtPath(DisabledInitializedPrefabAssetPath, typeof(Object)); var result = Object.Instantiate(checkboxesPrefab, Vector3.forward * 1.0f, Quaternion.identity) as GameObject; var interactables = result.GetComponentsInChildren <Interactable>(true); TestUtilities.PlaceRelativeToPlayspace(result.transform); const int ExpectedCheckboxCount = 2; Assert.AreEqual(ExpectedCheckboxCount, interactables.Length); bool isFirstActive = interactables[0].gameObject.activeInHierarchy; var enabledCheckbox = isFirstActive ? interactables[0] : interactables[1]; var disabledCheckbox = isFirstActive ? interactables[1] : interactables[0]; // No error messages should fire. enabledCheckbox.IsToggled = true; Assert.IsTrue(enabledCheckbox.IsToggled); // Disabled checkbox should auto-initialize even though its Awake() has not been called disabledCheckbox.IsToggled = true; Assert.IsTrue(disabledCheckbox.IsToggled); // Checkbox should still behave as expected even though it was pre-initialized { disabledCheckbox.gameObject.SetActive(true); disabledCheckbox.IsToggled = false; // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; disabledCheckbox.OnClick.AddListener(() => { wasClicked = true; }); Vector3 end = disabledCheckbox.transform.position - TestUtilities.DirectionRelativeToPlayspace(new Vector3(0f, 0.05f, 0f)); Vector3 start = end - TestUtilities.DirectionRelativeToPlayspace(new Vector3(0f, 0f, 0.5f)); yield return(TestButtonUtilities.MoveHand(start, end)); yield return(TestButtonUtilities.MoveHand(end, start)); Assert.True(wasClicked, "Interactable was not clicked."); } GameObject.Destroy(result); }
public IEnumerator TestPointerCaching() { TestButtonUtilities.InstantiateDefaultButton(TestButtonUtilities.DefaultButtonType.DefaultPushButton, out Interactable interactable, out Transform translateTargetObject); Vector3 targetStartPosition = translateTargetObject.localPosition; // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); var rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(Vector3.right)); var rightPokePointer = PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right); Assert.IsNotNull(rightPokePointer); Assert.IsFalse(rightPokePointer.DestroyOnSourceLost); yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject)); Assert.IsTrue(wasClicked); Assert.IsNotNull(rightPokePointer); Assert.IsNull(PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right)); wasClicked = false; yield return(rightHand.Show(Vector3.right)); // Confirm that we are re-using the same pointer gameobject that was stored in the cache Assert.AreEqual(rightPokePointer, PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right)); yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject)); Assert.IsTrue(wasClicked); Assert.IsNotNull(rightPokePointer); Assert.IsNull(PlayModeTestUtilities.GetPointer <PokePointer>(Handedness.Right)); }
public IEnumerator TestHandInputOnRuntimeAssembled() { AssembleInteractableButton( out Interactable interactable, out Transform translateTargetObject); interactable.transform.position = new Vector3(0.025f, 0.05f, 0.65f); interactable.transform.eulerAngles = new Vector3(-90f, 0f, 0f); TestUtilities.PlaceRelativeToPlayspace(interactable.transform); // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); Vector3 targetStartPosition = translateTargetObject.transform.localPosition; yield return(null); // Add a touchable and configure for touch events NearInteractionTouchable touchable = interactable.gameObject.AddComponent <NearInteractionTouchable>(); touchable.EventsToReceive = TouchableEventType.Touch; touchable.SetBounds(Vector2.one); touchable.SetLocalForward(Vector3.up); touchable.SetLocalUp(Vector3.forward); touchable.SetLocalCenter(Vector3.up * 2.75f); // Add a touch handler and link touch started / touch completed events TouchHandler touchHandler = interactable.gameObject.AddComponent <TouchHandler>(); touchHandler.OnTouchStarted.AddListener((HandTrackingInputEventData e) => interactable.SetInputDown()); touchHandler.OnTouchCompleted.AddListener((HandTrackingInputEventData e) => interactable.SetInputUp()); yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject)); Assert.True(wasClicked, "Interactable was not clicked."); GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestRadialSetPrefab() { var radialSet = TestButtonUtilities.InstantiateInteractableFromPath(Vector3.forward, Quaternion.identity, RadialSetPrefabAssetPath); var firstRadialButton = radialSet.transform.Find("Radial (1)").GetComponent <Interactable>(); var secondRadialButton = radialSet.transform.Find("Radial (2)").GetComponent <Interactable>(); var thirdRadialButton = radialSet.transform.Find("Radial (3)").GetComponent <Interactable>(); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(Vector3.zero)); Assert.IsTrue(firstRadialButton.IsToggled); Assert.IsFalse(secondRadialButton.IsToggled); Assert.IsFalse(thirdRadialButton.IsToggled); var aBitBack = Vector3.forward * -0.2f; yield return(testHand.MoveTo(secondRadialButton.transform.position)); yield return(testHand.Move(aBitBack)); Assert.IsFalse(firstRadialButton.IsToggled); Assert.IsFalse(firstRadialButton.HasFocus); Assert.IsTrue(secondRadialButton.IsToggled); Assert.IsTrue(secondRadialButton.HasFocus); Assert.IsFalse(thirdRadialButton.IsToggled); Assert.IsFalse(thirdRadialButton.HasFocus); yield return(testHand.MoveTo(thirdRadialButton.transform.position)); yield return(testHand.Move(aBitBack)); Assert.IsFalse(firstRadialButton.IsToggled); Assert.IsFalse(firstRadialButton.HasFocus); Assert.IsFalse(secondRadialButton.IsToggled); Assert.IsFalse(secondRadialButton.HasFocus); Assert.IsTrue(thirdRadialButton.IsToggled); Assert.IsTrue(thirdRadialButton.HasFocus); GameObject.Destroy(radialSet); }
public IEnumerator TestTriggerOnClick() { TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultPushButton, out Interactable interactable, out Transform innerCylinderTransform); // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); Vector3 targetStartPosition = innerCylinderTransform.localPosition; // // Test TriggerOnClick when disabled // interactable.IsEnabled = false; interactable.TriggerOnClick(); Assert.False(wasClicked, "Interactable was clicked."); Assert.False(interactable.IsVisited, "Interactable was visited."); // // Test TriggerOnClick when enabled // interactable.IsEnabled = true; interactable.TriggerOnClick(); yield return(new WaitForSeconds(ButtonReleaseAnimationDelay)); Assert.True(wasClicked, "Interactable was not clicked."); Assert.True(interactable.IsVisited, "Interactable was not visited."); GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestDisabledOnStart() { // Instantiate model_pushbutton prefab but with enabled on start false TestButtonUtilities.InstantiatePressableButtonPrefab( new Vector3(0.025f, 0.05f, 0.5f), TestButtonUtilities.DefaultRotation, DisabledOnStartPrefabAssetPath, "Cylinder", out Interactable interactable, out Transform pressButtonCylinder); // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); Vector3 targetStartPosition = pressButtonCylinder.localPosition; // // Test starting as disabled // yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, pressButtonCylinder, false)); Assert.False(wasClicked, "Interactable was clicked."); // // Test when enabled // interactable.IsEnabled = true; yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, pressButtonCylinder, true)); Assert.True(wasClicked, "Interactable was not clicked."); // Cleanup GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestHandInputOnPrefab() { TestButtonUtilities.InstantiatePressableButtonPrefab( new Vector3(0.025f, 0.05f, 0.5f), TestButtonUtilities.DefaultRotation, TestButtonUtilities.DefaultInteractablePrefabAssetPath, "Cylinder", out Interactable interactable, out Transform translateTargetObject); // Subscribe to interactable's on click so we know the click went through bool wasClicked = false; interactable.OnClick.AddListener(() => { wasClicked = true; }); Vector3 targetStartPosition = translateTargetObject.localPosition; yield return(TestButtonUtilities.TestClickPushButton(interactable.transform, targetStartPosition, translateTargetObject)); Assert.True(wasClicked, "Interactable was not clicked."); //Cleanup GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestButtonStateResetWhenFocusLostAfterPinch() { TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultHL2Button, out Interactable interactable, out Transform interactableTransform); interactable.transform.position = new Vector3(0.0f, 0.1f, 0.4f); Assert.True(interactable.IsEnabled); var rightHand = new TestHand(Handedness.Right); Vector3 focusPosition = new Vector3(0.015f, 0.015f, 0.3f); Vector3 releaseDelta = new Vector3(0.05f, 0, 0); // Focus the hand on the Button using the far ray pointer yield return(rightHand.Show(focusPosition)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Focus, "Interactable State is not Focus"); // While keeping focus on the Button, engage the pinch gesture yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.True(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Pressed, "Interactable State is not Pressed"); // Move Hand to remove focus. Button should go to Default State yield return(rightHand.Move(releaseDelta)); yield return(new WaitForSeconds(0.25f));// Wait for Interactable rollOffTime for HasPress to reset Assert.False(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Default, "Interactable State is not Default"); // Open hand. Button should stay on Default State yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.False(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Default, "Interactable State is not Default"); // Move Hand back to Initial position and Pinch. Button should go to Pressed State yield return(rightHand.Move(-releaseDelta)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.True(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Pressed, "Interactable State is not Pressed"); // Open Hand. Button should go to Focus State yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Focus, "Interactable State is not Focus"); GameObject.Destroy(interactable.gameObject); }
public IEnumerator TestButtonStateResetWhenFocusLostAfterPinch() { /// This test breaks if there is roll on the camera. I don't know if that's a real /// break, or an error in the test. Nulling out roll for now. Pose restorePose = TestUtilities.ArbitraryPlayspacePose; Pose noRollPose = restorePose; noRollPose.rotation.eulerAngles = new Vector3(noRollPose.rotation.eulerAngles.x, noRollPose.rotation.eulerAngles.y, 0.0f); TestUtilities.ArbitraryPlayspacePose = noRollPose; TestUtilities.PlayspaceToArbitraryPose(); TestButtonUtilities.InstantiateDefaultButton( TestButtonUtilities.DefaultButtonType.DefaultHL2Button, out Interactable interactable, out Transform interactableTransform); interactable.transform.position = TestUtilities.PositionRelativeToPlayspace(new Vector3(0.0f, 0.1f, 0.4f)); Assert.True(interactable.IsEnabled); var rightHand = new TestHand(Handedness.Right); Vector3 focusPosition = TestUtilities.PositionRelativeToPlayspace(new Vector3(0.0155f, 0.0145f, 0.3f)); Vector3 releaseDelta = TestUtilities.DirectionRelativeToPlayspace(new Vector3(0.05f, 0, 0)); // Focus the hand on the Button using the far ray pointer yield return(rightHand.Show(focusPosition)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Focus, "Interactable State is not Focus"); // While keeping focus on the Button, engage the pinch gesture yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.True(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Pressed, "Interactable State is not Pressed"); // Move Hand to remove focus. Button should go to Default State yield return(rightHand.Move(releaseDelta)); yield return(new WaitForSeconds(0.25f));// Wait for Interactable rollOffTime for HasPress to reset Assert.False(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Default, "Interactable State is not Default"); // Open hand. Button should stay on Default State yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.False(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Default, "Interactable State is not Default"); // Move Hand back to Initial position and Pinch. Button should go to Pressed State yield return(rightHand.Move(-releaseDelta)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.True(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Pressed, "Interactable State is not Pressed"); // Open Hand. Button should go to Focus State yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(interactable.HasFocus); Assert.False(interactable.HasPress); Assert.False(interactable.HasGesture); Assert.True(interactable.StateManager.CurrentState().Index == (int)InteractableStates.InteractableStateEnum.Focus, "Interactable State is not Focus"); GameObject.Destroy(interactable.gameObject); TestUtilities.ArbitraryPlayspacePose = restorePose; }