public IEnumerator PrefabScrollUpZoomOutLimited() { var maxPanHorizontal = 4f; var maxPanVertical = 4f; InstantiatePanLimitedSlateFromPrefab(maxPanHorizontal: maxPanHorizontal, maxPanVertical: maxPanVertical); yield return(ScrollToLimit(new Vector3(1, 1, 0))); // Right hand pinches slate TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.MoveTo(panZoom.transform.position + Vector3.forward * -0.5f + Vector3.right * 0.2f)); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Left hand pinches slate TestHand handLeft = new TestHand(Handedness.Left); yield return(handLeft.Show(panZoom.transform.position + Vector3.forward * -0.5f + Vector3.right * -0.2f)); yield return(handLeft.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Use both hands to zoom out yield return(handLeft.Move(new Vector3(0.1f, 0.1f, 0f), 10)); var uvs = new List <Vector2>(); meshFilter.mesh.GetUVs(0, uvs); #if UNITY_2019_1_OR_NEWER Assert.AreEqual(maxPanHorizontal * material.mainTextureScale.x, uvs[3].x, 0.05, "mesh uv is not correct"); Assert.AreEqual(maxPanVertical * material.mainTextureScale.y, uvs[3].y, 0.05, "mesh uv is not correct"); #else Assert.AreEqual(maxPanHorizontal * material.mainTextureScale.x, uvs[1].x, 0.05, "mesh uv is not correct"); Assert.AreEqual(maxPanVertical * material.mainTextureScale.y, uvs[1].y, 0.05, "mesh uv is not correct"); #endif yield return(handRight.Hide()); yield return(handLeft.Hide()); }
public IEnumerator TestGaze() { PointerStateContainer gazeOn = new PointerStateContainer() { GazePointerEnabled = true, GGVPointerEnabled = true, PokePointerEnabled = null, SpherePointerEnabled = null, LinePointerEnabled = null }; // set input simulation mode to GGV PlayModeTestUtilities.SetControllerSimulationMode(ControllerSimulationMode.HandGestures); TestHand rightHand = new TestHand(Handedness.Right); TestHand leftHand = new TestHand(Handedness.Left); TestContext.Out.WriteLine("Show both hands"); yield return(rightHand.Show(Vector3.zero)); yield return(leftHand.Show(Vector3.zero)); EnsurePointerStates(Handedness.Right, gazeOn); EnsurePointerStates(Handedness.Left, gazeOn); TestContext.Out.WriteLine("Turn off gaze cursor"); PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff); yield return(null); PointerStateContainer gazeOff = new PointerStateContainer() { GazePointerEnabled = false, GGVPointerEnabled = false, PokePointerEnabled = null, SpherePointerEnabled = null, LinePointerEnabled = null }; EnsurePointerStates(Handedness.Right, gazeOff); EnsurePointerStates(Handedness.Left, gazeOff); }
public IEnumerator TestDestroyFocusLockedObject() { TestUtilities.PlayspaceToOriginLookingForward(); var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.AddComponent <ObjectManipulator>(); // Add focus handler so focus can lock cube.transform.position = Vector3.right; cube.transform.localScale = Vector3.one * 0.2f; const int numHandSteps = 1; // No initial focus cube.transform.position = Vector3.forward; TestHand hand = new TestHand(Handedness.Right); yield return(hand.Show(Vector3.forward * 0.5f)); yield return(null); var handRayPointer = hand.GetPointer <ShellHandRayPointer>(); Assert.IsNull(handRayPointer.Result.CurrentPointerTarget); // Focus lock cube yield return(hand.MoveTo(new Vector3(0.06f, -0.1f, 0.5f), numHandSteps)); yield return(hand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(null); Assert.IsTrue(handRayPointer.IsFocusLocked); Assert.AreEqual(cube, handRayPointer.Result.CurrentPointerTarget); // Destroy the cube Object.DestroyImmediate(cube); yield return(null); Assert.IsFalse(handRayPointer.IsFocusLocked); Assert.IsNull(handRayPointer.Result.CurrentPointerTarget); // Verify that CurrentPointer is not still referencing the destroyed GameObject Assert.IsTrue(ReferenceEquals(handRayPointer.Result.CurrentPointerTarget, null)); }
public IEnumerator TestAssembeInteractableAndEventsRaised() { GameObject pinchSliderObject; PinchSlider slider; // This should not throw exception AssembleSlider(Vector3.forward, Vector3.zero, out pinchSliderObject, out slider); var rightHand = new TestHand(Handedness.Right); Vector3 initialPos = new Vector3(0.05f, 0, 1.0f); bool interactionStarted = false; slider.OnInteractionStarted.AddListener((x) => interactionStarted = true); yield return(rightHand.Show(initialPos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); Assert.IsTrue(interactionStarted, "Slider did not raise interaction started."); bool interactionUpdated = false; slider.OnValueUpdated.AddListener((x) => interactionUpdated = true); yield return(rightHand.Move(new Vector3(0.1f, 0, 0))); Assert.IsTrue(interactionUpdated, "Slider did not raise SliderUpdated event."); bool interactionEnded = false; slider.OnInteractionEnded.AddListener((x) => interactionEnded = true); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.Hide()); Assert.IsTrue(interactionEnded, "Slider did not raise interaction ended."); Assert.That(slider.SliderValue, Is.GreaterThan(0.5)); GameObject.Destroy(pinchSliderObject); }
/// <summary> /// Scroll a slate using GGV and ensure that the slate scrolls /// expected amount. Assumes panZoom has already been created. /// </summary> /// <param name="expectedScroll">The amount panZoom is expected to scroll</param> private IEnumerator RunGGVScrollTest(float expectedScroll) { PlayModeTestUtilities.SetHandSimulationMode(HandSimulationMode.Gestures); Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand h = new TestHand(Handedness.Right); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(h.Show(Vector3.zero)); yield return(h.Move(new Vector3(0.0f, -0.1f, 0f))); Assert.AreEqual(expectedScroll, totalPanDelta.y, 0.05, "pan delta is not correct"); yield return(h.Hide()); }
public IEnumerator HandRayTest() { yield return(null); Vector3 rightHandOrigin = new Vector3(-0.3f, -0.1f, 0.5f); // Create a hand (we will use the right hand) TestHand rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(rightHandOrigin)); Ray ray; bool success; TestContext.Out.WriteLine("Get the right hand ray"); success = InputRayUtils.TryGetHandRay(Handedness.Right, out ray); Assert.True(success, "TryGetHandRay did not succeed"); TestUtilities.AssertAboutEqual(ray.origin, rightHandOrigin, "hand ray origin is not correct", 0.1f); TestUtilities.AssertAboutEqual(ray.direction, new Vector3(-0.7f, 0.2f, 0.7f), "hand ray direction is not correct", 0.1f); }
public IEnumerator TestDisableFocusObject() { TestUtilities.PlayspaceToOriginLookingForward(); var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.position = Vector3.right; cube.transform.localScale = Vector3.one * 0.2f; const int numHandSteps = 1; // No initial focus cube.transform.position = Vector3.forward; TestHand hand = new TestHand(Handedness.Right); yield return(hand.Show(Vector3.forward * 0.5f)); yield return(null); var handRayPointer = hand.GetPointer <ShellHandRayPointer>(); Assert.IsNull(handRayPointer.Result.CurrentPointerTarget); // Focus on cube yield return(hand.MoveTo(new Vector3(0.06f, -0.1f, 0.5f), numHandSteps)); yield return(null); Assert.AreEqual(cube, handRayPointer.Result.CurrentPointerTarget); // Deactivate the cube cube.SetActive(false); yield return(null); Assert.IsNull(handRayPointer.Result.CurrentPointerTarget); // Reactivate the cube cube.SetActive(true); yield return(null); Assert.AreEqual(cube, handRayPointer.Result.CurrentPointerTarget); }
public IEnumerator TestRadialSetPrefab() { var radialSet = 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); //Cleanup GameObject.Destroy(radialSet); }
public IEnumerator ArticulatedCursorState() { var inputSystem = PlayModeTestUtilities.GetInputSystem(); // Show hand far enough from the test collider so the cursor is not on it var hand = new TestHand(Handedness.Right); Vector3 offObjectPos = TestUtilities.PositionRelativeToPlayspace(new Vector3(0.05f, 0, 1.0f)); yield return(hand.Show(offObjectPos)); VerifyCursorStateFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorStateEnum.Interact); // Move hand closer to the collider so the cursor is on it Vector3 onObjectPos = TestUtilities.PositionRelativeToPlayspace(new Vector3(0.05f, 0, 1.5f)); yield return(hand.MoveTo(onObjectPos, numFramesPerMove)); VerifyCursorStateFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorStateEnum.InteractHover); // Trigger pinch yield return(hand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); VerifyCursorStateFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorStateEnum.Select); // Release pinch yield return(hand.SetGesture(ArticulatedHandPose.GestureId.Open, false)); VerifyCursorStateFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorStateEnum.Release); // Wait to transition back to InteractHover yield return(null); VerifyCursorStateFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorStateEnum.InteractHover); // Move back so the cursor is no longer on the object yield return(hand.MoveTo(offObjectPos, numFramesPerMove)); VerifyCursorStateFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorStateEnum.Interact); yield return(null); }
public IEnumerator TestGazeProviderTargetNotNull() { TestUtilities.PlayspaceToOriginLookingForward(); var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.transform.position = Vector3.forward; yield return(null); yield return(null); Assert.NotNull(CoreServices.InputSystem.GazeProvider.GazeTarget, "GazeProvider target is null when looking at an object"); TestHand h = new TestHand(Handedness.Right); yield return(h.Show(Vector3.forward * 0.2f)); yield return(null); Assert.NotNull(CoreServices.InputSystem.GazeProvider.GazeTarget, "GazeProvider target is null when looking at an object with hand raised"); }
public IEnumerator TestRiggedHand() { // Initialize hand var rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(Vector3.zero)); RiggedHandVisualizer handVisualizer = GameObject.FindObjectOfType <RiggedHandVisualizer>().GetComponent <RiggedHandVisualizer>(); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); Assert.IsTrue(handVisualizer.HandRenderer.sharedMaterial.GetFloat(handVisualizer.PinchStrengthMaterialProperty) < 0.5f); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Grab)); Assert.IsTrue(handVisualizer.HandRenderer.sharedMaterial.GetFloat(handVisualizer.PinchStrengthMaterialProperty) > 0.5f); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.OpenSteadyGrabPoint)); Assert.IsTrue(handVisualizer.HandRenderer.sharedMaterial.GetFloat(handVisualizer.PinchStrengthMaterialProperty) < 0.5f); }
public IEnumerator PrefabZoomOutWithoutJitter() { var maxPan = 1.2f; InstantiatePanLimitedSlateFromPrefab(maxPanHorizontal: maxPan, maxPanVertical: maxPan); yield return(ScrollToLimit(new Vector3(-1, -1, 0))); // Right hand pinches slate TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.MoveTo(panZoom.transform.position + Vector3.forward * -0.5f + Vector3.right * 0.2f)); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Left hand pinches slate TestHand handLeft = new TestHand(Handedness.Left); yield return(handLeft.Show(panZoom.transform.position + Vector3.forward * -0.5f + Vector3.right * -0.2f)); yield return(handLeft.SetGesture(ArticulatedHandPose.GestureId.Pinch)); // Use both hands to zoom out var previousUvs = new List <Vector2>(); meshFilter.mesh.GetUVs(0, previousUvs); for (var i = 0; i < 10; i++) { yield return(handLeft.Move(new Vector3(0f, 0.02f, 0f), 1)); var uvs = new List <Vector2>(); meshFilter.mesh.GetUVs(0, uvs); for (int j = 0; j < uvs.Count; j++) { Assert.AreEqual(previousUvs[j].x, uvs[j].x, 0.05, "mesh is jittering"); Assert.AreEqual(previousUvs[j].y, uvs[j].y, 0.05, "mesh is jittering"); } previousUvs = uvs; } }
public IEnumerator ScaleViaNearInteration() { const int numSteps = 2; var bbox = InstantiateSceneAndDefaultBbox(); bbox.ScaleHandleSize = 0.1f; yield return(null); var bounds = bbox.GetComponent <BoxCollider>().bounds; Assert.AreEqual(new Vector3(0, 0, 1.5f), bounds.center); Assert.AreEqual(new Vector3(.5f, .5f, .5f), bounds.size); var inputSimulationService = PlayModeTestUtilities.GetInputSimulationService(); // front right corner is corner 3 var frontRightCornerPos = bbox.ScaleCorners[3].transform.position; TestHand rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(new Vector3(0, 0, 0.5f))); var delta = new Vector3(0.1f, 0.1f, 0f); yield return(rightHand.MoveTo(frontRightCornerPos, numSteps)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(rightHand.Move(delta, numSteps)); var endBounds = bbox.GetComponent <BoxCollider>().bounds; TestUtilities.AssertAboutEqual(endBounds.center, new Vector3(0.033f, 0.033f, 1.467f), "endBounds incorrect center"); TestUtilities.AssertAboutEqual(endBounds.size, Vector3.one * .567f, "endBounds incorrect size"); GameObject.Destroy(bbox.gameObject); // Wait for a frame to give Unity a change to actually destroy the object yield return(null); }
public IEnumerator TestHoldEvents() { // Hold var holdReceiver = interactable.AddReceiver <InteractableOnHoldReceiver>(); bool didHold = false; holdReceiver.OnHold.AddListener(() => didHold = true); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(interactable.transform.position)); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(new WaitForSeconds(holdReceiver.HoldTime)); yield return(testHand.Hide()); Assert.True(didHold, "Did not receive hold event"); GameObject.Destroy(cube); yield return(null); }
/// <summary> /// Scroll a slate using GGV and ensure that the slate scrolls /// expected amount. Assumes panZoom has already been created. /// </summary> /// <param name="expectedScroll">The amount panZoom is expected to scroll</param> private IEnumerator RunGGVScrollTest(float expectedScroll) { PlayModeTestUtilities.SetHandSimulationMode(HandSimulationMode.Gestures); Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(handRight.Show(Vector3.zero)); // Move requires a slower action (i.e. higher numSteps) in order to // achieve a reliable pan. yield return(handRight.Move(new Vector3(0.0f, -0.1f, 0f), 30)); Assert.AreEqual(expectedScroll, totalPanDelta.y, 0.1, "pan delta is not correct"); yield return(handRight.Hide()); }
public IEnumerator Prefab_RayScroll() { InstantiateFromPrefab(Vector3.forward); Vector2 totalPanDelta = Vector2.zero; panZoom.PanUpdated.AddListener((hpd) => totalPanDelta += hpd.PanDelta); TestHand h = new TestHand(Handedness.Right); Vector3 screenPoint = CameraCache.Main.ViewportToScreenPoint(new Vector3(0.5f, 0.25f, 0.5f)); yield return(h.Show(CameraCache.Main.ScreenToWorldPoint(screenPoint))); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(h.Move(new Vector3(0, -0.05f, 0), 10)); yield return(h.SetGesture(ArticulatedHandPose.GestureId.Open)); Assert.AreEqual(0.1, totalPanDelta.y, 0.05, "pan delta is not correct"); yield return(h.Hide()); }
/// <summary> /// Scroll contents to the limit in the specified direction /// </summary> /// <param name="direction">Scroll direction</param> private IEnumerator ScrollToLimit(Vector3 direction) { TestHand handRight = new TestHand(Handedness.Right); yield return(handRight.Show(Vector3.zero)); Vector3 screenPoint = CameraCache.Main.ViewportToScreenPoint(new Vector3(0.5f, 0.0f, 0.5f)); var moveDelta = -0.5f * direction; for (var i = 0; i < 3; i++) { yield return(handRight.MoveTo(CameraCache.Main.ScreenToWorldPoint(screenPoint))); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(handRight.Move(moveDelta, 10)); yield return(handRight.SetGesture(ArticulatedHandPose.GestureId.Open)); } yield return(handRight.Hide()); }
public IEnumerator TestOverlap() { // Instantiate our test GameObject with solver. var testObjects = InstantiateTestSolver <Overlap>(); testObjects.handler.TrackedTargetType = TrackedObjectType.HandJoint; var targetTransform = testObjects.target.transform; TestUtilities.AssertAboutEqual(targetTransform.position, Vector3.zero, "Overlap not at original position"); TestUtilities.AssertAboutEqual(targetTransform.rotation, Quaternion.identity, "Overlap not at original rotation"); // Test that the solver flies to the position of the left hand var handPosition = Vector3.forward - Vector3.right; var handRotation = Quaternion.LookRotation(handPosition); var leftHand = new TestHand(Handedness.Left); yield return(leftHand.Show(handPosition)); yield return(leftHand.SetRotation(handRotation)); yield return(WaitForFrames(2)); var hand = PlayModeTestUtilities.GetInputSimulationService().GetHandDevice(Handedness.Left); Assert.IsNotNull(hand); Assert.IsTrue(hand.TryGetJoint(TrackedHandJoint.Palm, out MixedRealityPose pose)); TestUtilities.AssertAboutEqual(targetTransform.position, pose.Position, "Overlap solver is not at the same position as the left hand."); Assert.IsTrue(Quaternion.Angle(targetTransform.rotation, pose.Rotation) < 2.0f); // Make sure the solver did not move when hand was hidden yield return(leftHand.Hide()); yield return(WaitForFrames(2)); TestUtilities.AssertAboutEqual(targetTransform.position, pose.Position, "Overlap solver moved when the hand was hidden."); Assert.IsTrue(Quaternion.Angle(targetTransform.rotation, pose.Rotation) < 2.0f); }
public IEnumerator TestToggleEvents() { var iss = PlayModeTestUtilities.GetInputSimulationService(); var oldSimMode = iss.ControllerSimulationMode; iss.ControllerSimulationMode = ControllerSimulationMode.HandGestures; var toggleReceiver = interactable.AddReceiver <InteractableOnToggleReceiver>(); interactable.transform.position = Vector3.forward * 2f; interactable.NumOfDimensions = 2; interactable.CanSelect = true; interactable.CanDeselect = true; bool didSelect = false; bool didUnselect = false; toggleReceiver.OnSelect.AddListener(() => didSelect = true); toggleReceiver.OnDeselect.AddListener(() => didUnselect = true); var testHand = new TestHand(Handedness.Right); yield return(testHand.Show(Vector3.forward)); CameraCache.Main.transform.LookAt(interactable.transform.position); yield return(testHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(testHand.Click()); yield return(testHand.Click()); yield return(testHand.Hide()); Assert.True(didSelect, "Toggle select did not fire"); Assert.True(didUnselect, "Toggle unselect did not fire"); iss.ControllerSimulationMode = oldSimMode; }
private IEnumerator DirectPinchAndMoveSlider(PinchSlider slider, float toSliderValue) { Debug.Log($"moving hand to value {toSliderValue}"); var rightHand = new TestHand(Handedness.Right); Vector3 initialPos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(initialPos)); yield return(rightHand.MoveTo(slider.ThumbRoot.transform.position)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); if (!(toSliderValue >= 0 && toSliderValue <= 1)) { throw new System.ArgumentException("toSliderValue must be between 0 and 1"); } yield return(rightHand.MoveTo(Vector3.Lerp(slider.SliderStartPosition, slider.SliderEndPosition, toSliderValue))); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.Hide()); }
public IEnumerator GrabVolumesWithOverlap() { // Initialize overlapRect and cube overlapRect.SetActive(true); overlapRect.transform.localScale = Vector3.one * 2; overlapRect.transform.position = Vector3.zero; cube.transform.localScale = Vector3.one; cube.transform.position = Vector3.zero; // Initialize hand var rightHand = new TestHand(Handedness.Right); yield return(rightHand.Show(Vector3.zero)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.OpenSteadyGrabPoint)); var pointer = rightHand.GetPointer <SpherePointer>(); Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller"); Assert.True(CoreServices.InputSystem.FocusProvider.GetFocusedObject(pointer) == cube, " the cube was not in focus"); Assert.True(pointer.IsNearObject); Assert.True(pointer.IsInteractionEnabled); // Switch the scale of the cube and rect overlapRect.transform.localScale = Vector3.one; cube.transform.localScale = Vector3.one * 2; // Wait for the input system to process the changes yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); Assert.True(CoreServices.InputSystem.FocusProvider.GetFocusedObject(pointer) == overlapRect, " the overlapping rectangle was not in focus"); // Reinitialize the overlapRect overlapRect.SetActive(false); }
public IEnumerator TestPointerFOV() { var rightHand = new TestHand(Handedness.Right); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); var cube = GameObject.CreatePrimitive(PrimitiveType.Cube); cube.AddComponent <NearInteractionGrabbable>(); cube.AddComponent <NearInteractionTouchableVolume>(); yield return(rightHand.Show(Vector3.zero)); yield return(PlayModeTestUtilities.WaitForInputSystemUpdate()); var spherePointer = PointerUtils.GetPointer <SpherePointer>(Handedness.Right); var pokePointer = PointerUtils.GetPointer <PokePointer>(Handedness.Right); yield return(TestPointerFOVHelper(spherePointer, cube, rightHand)); yield return(TestPointerFOVHelper(pokePointer, cube, rightHand)); rightHand.Hide(); GameObject.Destroy(cube); }
public IEnumerator Prefab_TouchZoom() { InstantiateFromPrefab(Vector3.forward); TestHand h = new TestHand(Handedness.Right); yield return(h.Show(Vector3.zero)); yield return(h.MoveTo(panZoom.transform.position, 10)); TestHand h2 = new TestHand(Handedness.Left); yield return(h2.Show(Vector3.zero)); yield return(h2.MoveTo(panZoom.transform.position + Vector3.right * -0.01f, 10)); yield return(h.Move(new Vector3(0.01f, 0f, 0f))); yield return(h2.Move(new Vector3(-0.01f, 0f, 0f))); Assert.AreEqual(0.4, panZoom.CurrentScale, 0.1, "slate did not zoom in using two finger touch"); yield return(h.Hide()); }
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 CursorContextScaleRotate() { var inputSystem = PlayModeTestUtilities.GetInputSystem(); var empty = new GameObject(); var info = cube.AddComponent <CursorContextInfo>(); info.ObjectCenter = empty.transform; // Show hand on object var hand = new TestHand(Handedness.Right); Vector3 handPos = new Vector3(0.05f, 0, 1.5f); yield return(hand.Show(handPos)); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.None); // rotate, center north info.CurrentCursorAction = CursorContextInfo.CursorAction.Rotate; empty.transform.SetPositionAndRotation(cube.transform.position + Vector3.up, Quaternion.identity); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.RotateNorthSouth); // rotate, center east empty.transform.SetPositionAndRotation(cube.transform.position + Vector3.right, Quaternion.identity); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.RotateEastWest); // scale, center northeast info.CurrentCursorAction = CursorContextInfo.CursorAction.Scale; empty.transform.SetPositionAndRotation(cube.transform.position + Vector3.up + Vector3.right, Quaternion.identity); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveNortheastSouthwest); // scale, center southeast empty.transform.SetPositionAndRotation(cube.transform.position + Vector3.down + Vector3.right, Quaternion.identity); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveNorthwestSoutheast); // scale, center northwest empty.transform.SetPositionAndRotation(cube.transform.position + Vector3.up + Vector3.left, Quaternion.identity); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveNorthwestSoutheast); // scale, center southwest empty.transform.SetPositionAndRotation(cube.transform.position + Vector3.down + Vector3.left, Quaternion.identity); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveNortheastSouthwest); Object.Destroy(empty); Object.Destroy(info); }
public IEnumerator CursorContextMove() { var inputSystem = PlayModeTestUtilities.GetInputSystem(); // The cube needs to be moved from under the gaze cursor before we add the manipulation handler. // Because the cube is under the gaze cursor from the beginning, it gets a focus gained event // in Setup(). When we show the right hand, we get a focus lost event from the gaze pointer. // This messes with the CursorContextManipulationHandler hoverCount, as it decrements without // ever having incremented. To avoid this, we move the cube out of focus before we add the // ManipulationHandler and CursorContextManipulationHandler. cube.transform.localPosition = new Vector3(0, -2, 2); yield return(new WaitForFixedUpdate()); yield return(null); cube.AddComponent <ManipulationHandler>(); var temp = cube.AddComponent <CursorContextManipulationHandler>(); yield return(new WaitForFixedUpdate()); yield return(null); // Move cube back to original postion (described above) cube.transform.localPosition = new Vector3(0, 0, 2); yield return(new WaitForFixedUpdate()); yield return(null); // Show right hand on object var rightHand = new TestHand(Handedness.Right); Vector3 rightPos = new Vector3(0.05f, 0, 1.5f); yield return(rightHand.Show(rightPos)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.None); // Pinch right hand yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveCross); // Show left hand on object var leftHand = new TestHand(Handedness.Left); Vector3 leftPos = new Vector3(-0.05f, 0, 1.5f); yield return(rightHand.Hide()); yield return(leftHand.Show(leftPos)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.None); // Pinch left hand yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveCross); // Show both hands on object yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(rightHand.Show(rightPos)); yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Open)); yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorContextFromPointers(inputSystem.FocusProvider.GetPointers <ShellHandRayPointer>(), CursorContextEnum.MoveCross); Object.Destroy(cube.GetComponent <ManipulationHandler>()); Object.Destroy(cube.GetComponent <CursorContextManipulationHandler>()); }
public IEnumerator GestureCursorState() { var inputSystem = PlayModeTestUtilities.GetInputSystem(); var iss = PlayModeTestUtilities.GetInputSimulationService(); var oldIsp = iss.InputSimulationProfile; var isp = ScriptableObject.CreateInstance <MixedRealityInputSimulationProfile>(); isp.HandSimulationMode = HandSimulationMode.Gestures; iss.InputSimulationProfile = isp; Vector3 underPointerPos = new Vector3(0, 0, 2); Vector3 abovePointerPos = new Vector3(0, -2, 2); var rightHand = new TestHand(Handedness.Right); var leftHand = new TestHand(Handedness.Left); // No hands, pointer not on cube, hand open cube.transform.localPosition = abovePointerPos; yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Observe); // No hands, pointer on cube, hand open cube.transform.localPosition = underPointerPos; yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.ObserveHover); // Right hand, pointer not on cube, hand open cube.transform.localPosition = abovePointerPos; yield return(new WaitForFixedUpdate()); yield return(rightHand.Show(Vector3.zero)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Interact); // Both hands, pointer not on cube, hand open yield return(leftHand.Show(Vector3.zero)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Interact); // Left hand, pointer not on cube, hand open yield return(rightHand.Hide()); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Interact); // Left hand, pointer on cube, hand open cube.transform.localPosition = underPointerPos; yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.InteractHover); // Both hands, pointer on cube, hand open yield return(rightHand.Show(Vector3.zero)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.InteractHover); // Right hand, pointer on cube, hand open yield return(leftHand.Hide()); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.InteractHover); // Right hand, pointer on cube, hand pinched yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); // Left hand, pointer on cube, hand pinched yield return(rightHand.Hide()); yield return(leftHand.Show(Vector3.zero)); yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Both hands, pointer on cube, left pinched & right open yield return(rightHand.Show(Vector3.zero)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Both hands, pointer on cube, both pinched yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Both hands, pointer on cube, right pinched & left open yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Open)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Restore the input simulation profile iss.InputSimulationProfile = oldIsp; yield return(null); }
public IEnumerator GestureCursorState() { var inputSystem = PlayModeTestUtilities.GetInputSystem(); var iss = PlayModeTestUtilities.GetInputSimulationService(); var oldHandSimMode = iss.ControllerSimulationMode; iss.ControllerSimulationMode = ControllerSimulationMode.HandGestures; Vector3 underPointerPos = TestUtilities.PositionRelativeToPlayspace(new Vector3(0, 0, 2)); Vector3 abovePointerPos = TestUtilities.PositionRelativeToPlayspace(new Vector3(0, -2, 2)); Vector3 zeroPos = TestUtilities.PositionRelativeToPlayspace(Vector3.zero); var rightHand = new TestHand(Handedness.Right); var leftHand = new TestHand(Handedness.Left); // No hands, pointer not on cube, hand open cube.transform.localPosition = abovePointerPos; yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Observe); // No hands, pointer on cube, hand open cube.transform.localPosition = underPointerPos; yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.ObserveHover); // Right hand, pointer not on cube, hand open cube.transform.localPosition = abovePointerPos; yield return(new WaitForFixedUpdate()); yield return(rightHand.Show(zeroPos)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Interact); // Both hands, pointer not on cube, hand open yield return(leftHand.Show(zeroPos)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Interact); // Left hand, pointer not on cube, hand open yield return(rightHand.Hide()); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Interact); // Left hand, pointer on cube, hand open cube.transform.localPosition = underPointerPos; yield return(new WaitForFixedUpdate()); yield return(null); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.InteractHover); // Both hands, pointer on cube, hand open yield return(rightHand.Show(zeroPos)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.InteractHover); // Right hand, pointer on cube, hand open yield return(leftHand.Hide()); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.InteractHover); // Right hand, pointer on cube, hand pinched yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); // Left hand, pointer on cube, hand pinched yield return(rightHand.Hide()); yield return(leftHand.Show(zeroPos)); yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Both hands, pointer on cube, left pinched & right open yield return(rightHand.Show(zeroPos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Open)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Both hands, pointer on cube, both pinched yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.Pinch)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Both hands, pointer on cube, right pinched & left open yield return(leftHand.SetGesture(ArticulatedHandPose.GestureId.Open)); VerifyCursorState(inputSystem.GazeProvider.GazeCursor, CursorStateEnum.Select); // Restore the input simulation profile iss.ControllerSimulationMode = oldHandSimMode; yield return(null); }
public IEnumerator SpherePointerDistances() { var rightHand = new TestHand(Handedness.Right); // Show hand far enough from the test collider Vector3 idlePos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(idlePos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.OpenSteadyGrabPoint)); var pointer = rightHand.GetPointer <SpherePointer>(); pointer.NearObjectSectorAngle = 360.0f; pointer.PullbackDistance = 0.0f; Vector3 margin = new Vector3(0, 0, 0.001f); Vector3 nearObjectMargin = new Vector3(0, 0, 0.001f + (pointer.NearObjectSmoothingFactor + 1) * pointer.NearObjectRadius); Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller"); Vector3 nearObjectPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.NearObjectRadius); Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsNearObject yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(interactionEnabledPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.True(pointer.IsInteractionEnabled); // Move hand back out to disable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand back out to disable IsNearObject yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Testing that we have more leeway when the pointer's nearObject smoothing factor is set // Move hand back out to disable IsNearObject yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(idlePos, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); }
public IEnumerator SpherePointerSectorAngle() { var rightHand = new TestHand(Handedness.Right); // Show hand far enough from the test collider Vector3 idlePos = new Vector3(0.05f, 0, 1.0f); yield return(rightHand.Show(idlePos)); yield return(rightHand.SetGesture(ArticulatedHandPose.GestureId.OpenSteadyGrabPoint)); var pointer = rightHand.GetPointer <SpherePointer>(); pointer.NearObjectSectorAngle = 180.0f; pointer.PullbackDistance = 0.0f; // Orient the right hand so the grab axis is approximately aligned with the z axis Vector3 margin = new Vector3(0, 0, 0.001f); Vector3 nearObjectMargin = new Vector3(0, 0, 0.001f + (pointer.NearObjectSmoothingFactor + 1) * pointer.NearObjectRadius); Assert.IsNotNull(pointer, "Expected to find SpherePointer in the hand controller"); Vector3 nearObjectPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.NearObjectRadius); Vector3 interactionEnabledPos = new Vector3(0.05f, 0, colliderSurfaceZ - pointer.SphereCastRadius); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsNearObject yield return(rightHand.MoveTo(nearObjectPos - margin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Rotate hand but maintain IsNearObject yield return(rightHand.SetRotation(Quaternion.Euler(0, 90, 0), numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Rotate hand 200 degrees and lose IsNearObject yield return(rightHand.SetRotation(Quaternion.Euler(0, 200, 0), numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Rotate hand back to original orientation yield return(rightHand.SetRotation(Quaternion.Euler(0, 0, 0), numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand closer to the collider to enable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(interactionEnabledPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.True(pointer.IsInteractionEnabled); // Move hand back out to disable IsInteractionEnabled yield return(rightHand.MoveTo(interactionEnabledPos - margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); // Move hand back out to disable IsNearObject yield return(rightHand.MoveTo(nearObjectPos + margin, numFramesPerMove)); Assert.True(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(nearObjectPos - nearObjectMargin, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); yield return(rightHand.MoveTo(idlePos, numFramesPerMove)); Assert.False(pointer.IsNearObject); Assert.False(pointer.IsInteractionEnabled); }