/// <summary> /// Begin with the selection and movement of the focused target. /// </summary> public void DragAndDrop_Start() { if ((EyeTrackingProvider?.GazeTarget == gameObject) && (!objIsGrabbed)) { if (AudioFeedbackPlayer.Instance != null) { AudioFeedbackPlayer.Instance.PlaySound(audio_OnDragStart); } objIsGrabbed = true; EyeTrackingDemoUtils.GameObject_ChangeTransparency(gameObject, transparency_inTransition, ref originalTransparency); initialHandPos = handPos_absolute; initalGazeDir = new Vector3(EyeTrackingProvider.GazeDirection.x, EyeTrackingProvider.GazeDirection.y, EyeTrackingProvider.GazeDirection.z); Rigidbody rbody = GetComponent <Rigidbody>(); if (rbody != null) { originalUseGravity = rbody.useGravity; originalDrag = rbody.drag; rbody.useGravity = false; rbody.drag = float.PositiveInfinity; } OnDragStart.Invoke(); } }
/// <summary> /// Determine whether the user is looking away from the preview. /// </summary> /// <returns></returns> private bool IsLookingAwayFromPreview() { if (prevPreviewPos == null || EyeTrackingProvider == null) { return(true); } Vector3 eyes2PrevPreview = prevPreviewPos.Value - EyeTrackingProvider.GazeOrigin; Vector3 eye2HitPos = EyeTrackingProvider.GazeDirection; float angle = Vector3.Angle(eyes2PrevPreview, eye2HitPos); float distance = EyeTrackingDemoUtils.VisAngleInDegreesToMeters(Vector3.Angle(eyes2PrevPreview, eye2HitPos), eye2HitPos.magnitude); if (distance < previewPlacemDistThresh) { return(false); } // Check if the target is still hit by the eye gaze cursor if (EyeTrackingProvider.GazeTarget == previewGameObject) { return(false); } // Check whether the user is still looking within the proximity of the target float distanceBetweenTargetAndCurrHitPos = Angle_ToCurrHitTarget(previewGameObject); if (distanceBetweenTargetAndCurrHitPos > minLookAwayDistToEnableEyeWarp) { return(true); } return(false); }
/// <summary> /// Instantiates a new target and transforms it according to the given parameters. /// </summary> /// <param name="radius">Radius of the ring in which the target is placed in.</param> /// <param name="viewingDist">The distance between the target group and the camera.</param> /// <param name="iTarget">The index of the target within the current ring.</param> private void InstantiateRadialLayoutedTarget(float radius, float viewingDist, int iTarget) { GameObject _target = Instantiate(GetRandomTemplate()); // Position float xnew = transform.position.x + EyeTrackingDemoUtils.VisAngleInDegreesToMeters(radius, viewingDist) * Mathf.Cos(Mathf.Deg2Rad * iTarget * 360 / radialLayout_nTargets); float ynew = transform.position.y + EyeTrackingDemoUtils.VisAngleInDegreesToMeters(radius, viewingDist) * Mathf.Sin(Mathf.Deg2Rad * iTarget * 360 / radialLayout_nTargets); _target.transform.localPosition = new Vector3(xnew, ynew, transform.position.z); // Scale float dist2 = Vector3.Distance(CameraCache.Main.transform.position, _target.transform.position); Vector3 tmpTargetSizeInMeters = EyeTrackingDemoUtils.VisAngleInDegreesToMeters(targetSizeInVisAngle, dist2); _target.transform.localScale = tmpTargetSizeInMeters; // Name it _target.name = string.Format("target_r{0}_t{1}", radius, iTarget); // Assign parent _target.transform.SetParent(transform); _target.gameObject.SetActive(true); // Add it to our list of instantiated targets instantiatedTargets.Add(_target); }
/// <summary> /// If a new target entered the trigger zone and one of our desired targets recently has been dropped, /// the AreWeThereYet method is called to check if all desired targets are in the destination zone. /// </summary> private void AreWeThereYet() { bool areAllObjsInZone = true; // Check that each requested target is within the trigger zone. // Note, this does not check whether additional items have been placed in our trigger zone. for (int i = 0; i < ObjsToPlaceHere.Length; i++) { if ((ObjsToPlaceHere[i] != null) && (!currCollidingObjs.Contains(ObjsToPlaceHere[i].name))) { areAllObjsInZone = false; break; } } // Only change color if the status has changed if (areAllObjsInZone && !prevAllObjsInZone) { EyeTrackingDemoUtils.GameObject_ChangeColor(gameObject, statusColor_achieved, ref originalColor, false); AudioFeedbackPlayer.Instance.PlaySound(AudioFx_Success); } else if (!areAllObjsInZone && prevAllObjsInZone) { EyeTrackingDemoUtils.GameObject_ChangeColor(gameObject, statusColor_idle, ref originalColor, false); } prevAllObjsInZone = areAllObjsInZone; }
private void Start() { // Init our list of currently colliding game objects currCollidingObjs = new List <string>(); // Set default color EyeTrackingDemoUtils.GameObject_ChangeColor(gameObject, statusColor_idle, ref originalColor, false); }
/// <summary> /// Turn on the preview of the to-be-placed target. /// </summary> private void ActivatePreview() { if (previewGameObject == null) { previewGameObject = Instantiate(gameObject); previewGameObject.GetComponent <Collider>().enabled = false; EyeTrackingDemoUtils.GameObject_ChangeTransparency(previewGameObject, transparency_preview); placePreviewAtHitPoint = false; } previewGameObject.SetActive(true); }
/// <summary> /// Keeps the target size in visual angle constant. /// </summary> private void KeepConstantVisAngleTargetSize() { // Note: We could improve performance by checking the delta camera movement. If below thresh -> Don't update. foreach (GameObject gobj in instantiatedTargets) { if (gobj != null) { float distObjToCam = Vector3.Distance(CameraCache.Main.transform.position, gobj.transform.position); gobj.transform.localScale = EyeTrackingDemoUtils.VisAngleInDegreesToMeters(targetSizeInVisAngle, distObjToCam); } } }
/// <summary> /// Reset the target group iterator. /// </summary> public void ResetIterator() { currTargetIndex = 0; ResetAmountOfTries(); targets = GetComponent <TargetGroupCreatorRadial>().InstantiatedObjects; // Randomize the order in which targets are highlighted if (Randomize) { targets = EyeTrackingDemoUtils.RandomizeListOrder(targets); } // Show first highlighted target // Hide all targets first foreach (GameObject obj in targets) { obj.SetActive(!DeactiveDistractors); } // Then activate current target and highlight ShowHighlights(); }
/// <summary> /// Creates a group of instantiated targets in a radial layout. /// </summary> private void CreateNewTargets_RadialLayout() { instantiatedTargets = new List <GameObject>(); // Set target size float dist = Vector3.Distance(CameraCache.Main.transform.position, transform.position); targetSizeInMeters = EyeTrackingDemoUtils.VisAngleInDegreesToMeters(targetSizeInVisAngle, dist); // Let's store the local rotation and reset it for now to rotate it later with all children Vector3 rotate = transform.localRotation.eulerAngles; transform.localRotation = Quaternion.Euler(Vector3.zero); // Let's make sure we have some templates to work with if ((templates != null) && (templates.Length > 0)) { // Show a target at the center of the target group if (showTargetAtGroupCenter) { InstantiateRadialLayoutedTarget(0, dist, 0); } // Instantiate and place the remaining targets // Create different number of rings based on the amount of given radii for (int ir = 0; ir < radialLayout_radiusInVisAngle.Length; ir++) { // Per ring create a given number of targets for (int it = 0; it < radialLayout_nTargets; it++) { InstantiateRadialLayoutedTarget(radialLayout_radiusInVisAngle[ir], dist, it); } } // Rotate the target family transform.Rotate(rotate); } }
/// <summary> /// Finalize placing the currently selected target. /// </summary> public void DragAndDrop_Finish() { if (objIsGrabbed) { if (AudioFeedbackPlayer.Instance != null) { AudioFeedbackPlayer.Instance.PlaySound(audio_OnDragStop); } if (onlyEyeWarpOnRelease) { manualTargetManip = true; if (plausibleLocation.HasValue) { MoveTargetTo(plausibleLocation.Value); } } objIsGrabbed = false; DeactivatePreview(); EyeTrackingDemoUtils.GameObject_ChangeTransparency(gameObject, originalTransparency); Rigidbody rbody = GetComponent <Rigidbody>(); if (rbody != null) { rbody.useGravity = originalUseGravity; rbody.drag = originalDrag; } if (useAsSlider) { OnDrop_SnapToClosestDecimal(); } OnDrop.Invoke(); } }
/// <summary> /// Proceed to the next target. If the end is reached, fire an event that the target group has been fully /// iterated and restart the scene. /// </summary> private void ProceedToNextTarget() { Debug.Log("[TargetGroupIterator] >> Next target: " + currTargetIndex + " / " + nrOfTargetsToSelect); ResetAmountOfTries(); Fire_OnTargetSelected(); if (currTargetIndex < nrOfTargetsToSelect - 1) { // 1. Let's reset the highlight for the last target. HideHighlights(); // 2. If "DisableDistractors" is true then let's hide the selected target if (DeactiveDistractors) { CurrentTarget.gameObject.SetActive(false); } // 3. Let's update to highlight the new target. currTargetIndex++; ShowHighlights(); } else // At the end { // Fire an event to inform listeners that all targets have been iterated through. Fire_OnAllTargetsSelected(); // Play some audio feedback (e.g., a cheerful applause). AudioFeedbackPlayer.Instance.PlaySound(AudioApplauseOnFinish); // If a scene is given, reload the scene after a short timeout. if (SceneToLoadOnFinish != "") { StartCoroutine(EyeTrackingDemoUtils.LoadNewScene(SceneToLoadOnFinish, 0.1f)); } } }