/// <summary> /// This coroutine will fade out the view, perform the teleport, and then fade the view /// back in. /// </summary> /// <returns></returns> protected IEnumerator BlinkCoroutine() { LocomotionTeleport.IsTransitioning = true; float elapsedTime = 0; var teleportTime = TransitionDuration * TeleportDelay; var teleported = false; while (elapsedTime < TransitionDuration) { yield return(null); elapsedTime += Time.deltaTime; if (!teleported && elapsedTime >= teleportTime) { teleported = true; LocomotionTeleport.DoTeleport(); } float fadeLevel = FadeLevels.Evaluate(elapsedTime / TransitionDuration); GetComponent <OVRScreenFade>().SetFadeLevel(fadeLevel); } GetComponent <OVRScreenFade>().SetFadeLevel(0); LocomotionTeleport.IsTransitioning = false; }
protected virtual void OnDisable() { Debug.Assert(_eventsActive); RemoveEventHandlers(); Debug.Assert(!_eventsActive); LocomotionTeleport = null; }
/// <summary> /// This method will be called while the LocmotionTeleport component is in the aiming state, once for each /// line segment that the targeting beam requires. /// The function should return true whenever an actual target location has been selected. /// </summary> protected override bool ConsiderTeleport(Vector3 start, ref Vector3 end) { // If the ray hits the world, consider it valid and update the aimRay to the end point. if (!LocomotionTeleport.AimCollisionTest(start, end, AimCollisionLayerMask | TeleportLayerMask, out AimData.TargetHitInfo)) { return(false); } TeleportPoint tp = AimData.TargetHitInfo.collider.gameObject.GetComponent <TeleportPoint>(); if (tp == null) { return(false); } // The targeting test discovered a valid teleport node. Now test to make sure there is line of sight to the // actual destination. Since the teleport destination is expected to be right on the ground, use the LOSOffset // to bump the collision check up off the ground a bit. var dest = tp.destTransform.position; var offsetEnd = new Vector3(dest.x, dest.y + LOSOffset, dest.z); if (LocomotionTeleport.AimCollisionTest(start, offsetEnd, AimCollisionLayerMask & ~TeleportLayerMask, out AimData.TargetHitInfo)) { return(false); } end = dest; return(true); }
/// <summary> /// OnEnable is virtual so that derived classes can set up references to objects before /// AddEventHandlers is called, as is required by TeleportSupport derivations. /// </summary> protected virtual void OnEnable() { LocomotionTeleport = GetComponent <LocomotionTeleport>(); Debug.Assert(!_eventsActive); AddEventHandlers(); Debug.Assert(_eventsActive); }
/// <summary> /// This coroutine will fade out the view, perform the teleport, and then fade the view /// back in. /// </summary> /// <returns></returns> protected IEnumerator BlinkCoroutine() { LocomotionTeleport.IsTransitioning = true; float elapsedTime = 0; var teleportTime = TransitionDuration * TeleportDelay; var teleported = false; while (elapsedTime < TransitionDuration) { yield return(null); elapsedTime += Time.deltaTime; if (!teleported && elapsedTime >= teleportTime) { teleported = true; LocomotionTeleport.DoTeleport(); } //float fadeLevel = FadeLevels.Evaluate(elapsedTime / TransitionDuration); //OVRInspector.instance.fader.SetFadeLevel(fadeLevel); } //OVRInspector.instance.fader.SetFadeLevel(0); LocomotionTeleport.IsTransitioning = false; }
/// <summary> /// This version of ConsiderDestination will only return a valid location if the pathing system is able to find a route /// from the current position to the candidate location. /// </summary> /// <param name="location"></param> /// <returns></returns> public override Vector3?ConsiderDestination(Vector3 location) { var result = base.ConsiderDestination(location); if (result.HasValue) { Vector3 start = LocomotionTeleport.GetCharacterPosition(); Vector3 dest = result.GetValueOrDefault(); } return(null); }
/// <summary> /// This method will be called while the LocmotionTeleport component is in the aiming state, once for each /// line segment that the targeting beam requires. /// The function should return true whenever an actual target location has been selected. /// </summary> /// <param name="start"></param> /// <param name="end"></param> protected override bool ConsiderTeleport(Vector3 start, ref Vector3 end) { // If the ray hits the world, consider it valid and update the aimRay to the end point. if (LocomotionTeleport.AimCollisionTest(start, end, AimCollisionLayerMask, out AimData.TargetHitInfo)) { var d = (end - start).normalized; end = start + d * AimData.TargetHitInfo.distance; return(true); } return(false); }
/// <summary> /// This coroutine will be active during the teleport transition and will move the camera /// according to the PositionLerp curve. /// </summary> /// <returns></returns> IEnumerator DoWarp() { LocomotionTeleport.IsTransitioning = true; var startPosition = LocomotionTeleport.GetCharacterPosition(); float elapsedTime = 0; while (elapsedTime < TransitionDuration) { elapsedTime += Time.deltaTime; var t = elapsedTime / TransitionDuration; var pLerp = PositionLerp.Evaluate(t); LocomotionTeleport.DoWarp(startPosition, pLerp); yield return null; } LocomotionTeleport.DoWarp(startPosition, 1.0f); LocomotionTeleport.IsTransitioning = false; }
protected override void UpdateTeleportDestination() { // Only update the orientation during preteleport, or if configured to do updates during aim. if (AimData.Destination.HasValue && (UpdateOrientationDuringAim || LocomotionTeleport.CurrentState == LocomotionTeleport.States.PreTeleport)) { var t = LocomotionTeleport.LocomotionController.CameraRig.centerEyeAnchor; var destination = AimData.Destination.GetValueOrDefault(); // create a plane that contains the destination, with the normal pointing to the HMD. var plane = new Plane(Vector3.up, destination); // find the point on the plane that the HMD is looking at. float d; bool hit = plane.Raycast(new Ray(t.position, t.forward), out d); if (hit) { var target = t.position + t.forward * d; var local = target - destination; local.y = 0; var distance = local.magnitude; if (distance > AimDistanceThreshold) { local.Normalize(); // Some debug draw code to visualize what the math is doing. //OVRDebugDraw.AddCross(target, 0.2f, 0.01f, Color.yellow, 0.1f); //OVRDebugDraw.AddCross(destination + new Vector3(local.x, 0, local.z), 0.2f, 0.01f, Color.blue, 0.1f); //OVRDebugDraw.AddLine(t.position + new Vector3(0, 0.1f, 0), target, 0.01f, Color.yellow, 1.0f); //OVRDebugDraw.AddLine(target + new Vector3(0, 1f, 0), target - new Vector3(0, 1f, 0), 0.01f, Color.blue, 1.0f); var rot = Quaternion.LookRotation(new Vector3(local.x, 0, local.z), Vector3.up); _initialRotation = rot; if (AimDistanceMaxRange > 0 && distance > AimDistanceMaxRange) { AimData.TargetValid = false; } LocomotionTeleport.OnUpdateTeleportDestination(AimData.TargetValid, AimData.Destination, rot, GetLandingOrientation(OrientationMode, rot)); return; } } } LocomotionTeleport.OnUpdateTeleportDestination(AimData.TargetValid, AimData.Destination, _initialRotation, GetLandingOrientation(OrientationMode, _initialRotation)); }
/// <summary> /// This version of ConsiderDestination will only return a valid location if the pathing system is able to find a route /// from the current position to the candidate location. /// </summary> /// <param name="location"></param> /// <returns></returns> public override Vector3?ConsiderDestination(Vector3 location) { var result = base.ConsiderDestination(location); if (result.HasValue) { Vector3 start = LocomotionTeleport.GetCharacterPosition(); Vector3 dest = result.GetValueOrDefault(); UnityEngine.AI.NavMesh.CalculatePath(start, dest, NavMeshAreaMask, _path); if (_path.status == UnityEngine.AI.NavMeshPathStatus.PathComplete) { return(result); } } return(null); }
protected override void UpdateTeleportDestination() { var direction = OVRInput.Get(Thumbstick == Thumbsticks.LeftThumbstick ? OVRInput.RawAxis2D.LThumbstick : OVRInput.RawAxis2D.RThumbstick); if (!AimData.TargetValid) { _lastValidDirection = new Vector2(); } var length = direction.magnitude; if (length < RotateStickThreshold) { direction = _lastValidDirection; length = direction.magnitude; if (length < RotateStickThreshold) { _initialRotation = LocomotionTeleport.GetHeadRotationY(); direction.x = 0; direction.y = 1; } } else { _lastValidDirection = direction; } var tracking = LocomotionTeleport.LocomotionController.CameraRig.trackingSpace.rotation; if (length > RotateStickThreshold) { direction /= length; // normalize the vector var rot = _initialRotation * Quaternion.LookRotation(new Vector3(direction.x, 0, direction.y), Vector3.up); _currentRotation = tracking * rot; } else { _currentRotation = tracking * LocomotionTeleport.GetHeadRotationY(); } LocomotionTeleport.OnUpdateTeleportDestination(AimData.TargetValid, AimData.Destination, _currentRotation, GetLandingOrientation(OrientationMode, _currentRotation)); }
// Use this for initialization void Start() { _locomotionBehaviors = LocomotionController.GetComponents <MonoBehaviour>(); AddLabel("Input Handler"); _toggleAvatarTouch = SetupToggle <TeleportInputHandler, TeleportInputHandlerAvatarTouch>("Avatar Touch"); _toggleGenericHMD = SetupToggle <TeleportInputHandler, TeleportInputHandlerHMD>("Generic HMD"); AddLabel("Aim Handler"); _toggleLaser = SetupToggle <TeleportAimHandler, TeleportAimHandlerLaser>("Laser"); _toggleParabolic = SetupToggle <TeleportAimHandler, TeleportAimHandlerParabolic>("Parabolic"); AddLabel("Target Handler"); _toggleNavMesh = SetupToggle <TeleportTargetHandler, TeleportTargetHandlerNavMesh>("Nav Mesh"); _toggleTeleportNode = SetupToggle <TeleportTargetHandler, TeleportTargetHandlerNode>("Teleport Node"); _toggleGeometry = SetupToggle <TeleportTargetHandler, TeleportTargetHandlerPhysical>("Geometry"); AddLabel("Orientation Handler"); _toggle360 = SetupToggle <TeleportOrientationHandler, TeleportOrientationHandler360>("360"); _toggleHMD = SetupToggle <TeleportOrientationHandler, TeleportOrientationHandlerHMD>("HMD"); _toggleThumbstickRelative = SetupToggle <TeleportOrientationHandler, TeleportOrientationHandlerThumbstick>("Thumbstick Head Relative", TeleportOrientationHandler.OrientationModes.HeadRelative); _toggleThumbstickForward = SetupToggle <TeleportOrientationHandler, TeleportOrientationHandlerThumbstick>("Thumbstick Forward Facing", TeleportOrientationHandler.OrientationModes.ForwardFacing); AddLabel("Transition"); _toggleInstant = SetupToggle <TeleportTransition, TeleportTransitionInstant>("Instant"); _toggleBlink = SetupToggle <TeleportTransition, TeleportTransitionBlink>("Blink"); _toggleWarp = SetupToggle <TeleportTransition, TeleportTransitionWarp>("Warp (no orientation)"); AddLabel("Enable Linear Motion During Teleport States"); _teleportController = LocomotionController.GetComponent <LocomotionTeleport>(); _toggleLinearMotionReady = SetupToggle("Ready State Motion", ToggleReadyStateMotion); _toggleLinearMotionAim = SetupToggle("Aim State Motion", ToggleAimStateMotion); _toggleLinearMotionPreTeleport = SetupToggle("PreTeleport State Motion", TogglePreTeleportStateMotion); _toggleLinearMotionPostTeleport = SetupToggle("PostTeleport State Motion", TogglePostTeleportStateMotion); AddLabel("Enable Rotation During Teleport States"); _teleportController = LocomotionController.GetComponent <LocomotionTeleport>(); _toggleRotationReady = SetupToggle("Ready State Rotation", ToggleReadyStateRotation); _toggleRotationAim = SetupToggle("Aim State Rotation", ToggleAimStateRotation); _toggleRotationPreTeleport = SetupToggle("PreTeleport State Rotation", TogglePreTeleportStateRotation); _toggleRotationPostTeleport = SetupToggle("PostTeleport State Rotation", TogglePostTeleportStateRotation); ToggleTemplate.SetActive(false); LabelTemplate.SetActive(false); }
/// <summary> /// This coroutine is active while the teleport system is in the aiming state. /// </summary> /// <returns></returns> private IEnumerator TargetAimCoroutine() { // While the teleport system is in the aim state, perform the aim logic and consider teleporting. while (LocomotionTeleport.CurrentState == LocomotionTeleport.States.Aim) { // With each targeting test, we need to reset the AimData to clear the point list and reset flags. ResetAimData(); // Start the testing with the character's current position to the aiming origin to ensure they // haven't just stuck their hand through something that should have prevented movement. // // The first test won't be added to the aim data results because the visual effects should be from // the aiming origin. var current = LocomotionTeleport.transform.position; // Enumerate through all the line segments provided by the aim handler, checking for a valid target on each segment, // stopping at the first valid target or when the enumerable runs out of line segments. _aimPoints.Clear(); LocomotionTeleport.AimHandler.GetPoints(_aimPoints); for (int i = 0; i < _aimPoints.Count; i++) { var adjustedPoint = _aimPoints[i]; AimData.TargetValid = ConsiderTeleport(current, ref adjustedPoint); AimData.Points.Add(adjustedPoint); if (AimData.TargetValid) { AimData.Destination = ConsiderDestination(adjustedPoint); AimData.TargetValid = AimData.Destination.HasValue; break; } current = _aimPoints[i]; } LocomotionTeleport.OnUpdateAimData(AimData); yield return(null); } }
protected override void OnDisable() { base.OnDisable(); LocomotionTeleport = null; }
protected override void UpdateTeleportDestination() { float magnitude; Vector2 direction; if (Thumbstick == OVRInput.Controller.Touch) { Vector2 leftDir = OVRInput.Get(OVRInput.RawAxis2D.LThumbstick); Vector2 rightDir = OVRInput.Get(OVRInput.RawAxis2D.RThumbstick); float leftMag = leftDir.magnitude; float rightMag = rightDir.magnitude; if (leftMag > rightMag) { magnitude = leftMag; direction = leftDir; } else { magnitude = rightMag; direction = rightDir; } } else { if (Thumbstick == OVRInput.Controller.LTouch) { direction = OVRInput.Get(OVRInput.RawAxis2D.LThumbstick); } else { direction = OVRInput.Get(OVRInput.RawAxis2D.RThumbstick); } magnitude = direction.magnitude; } if (!AimData.TargetValid) { _lastValidDirection = new Vector2(); } if (magnitude < RotateStickThreshold) { direction = _lastValidDirection; magnitude = direction.magnitude; if (magnitude < RotateStickThreshold) { _initialRotation = LocomotionTeleport.GetHeadRotationY(); direction.x = 0; direction.y = 1; } } else { _lastValidDirection = direction; } var tracking = LocomotionTeleport.LocomotionController.CameraRig.trackingSpace.rotation; if (magnitude > RotateStickThreshold) { direction /= magnitude; // normalize the vector var rot = _initialRotation * Quaternion.LookRotation(new Vector3(direction.x, 0, direction.y), Vector3.up); _currentRotation = tracking * rot; } else { _currentRotation = tracking * LocomotionTeleport.GetHeadRotationY(); } LocomotionTeleport.OnUpdateTeleportDestination(AimData.TargetValid, AimData.Destination, _currentRotation, GetLandingOrientation(OrientationMode, _currentRotation)); }
protected override void InitializeTeleportDestination() { _initialRotation = LocomotionTeleport.GetHeadRotationY(); _currentRotation = _initialRotation; _lastValidDirection = new Vector2(); }
protected override void OnEnable() { LocomotionTeleport = GetComponent <LocomotionTeleport>(); base.OnEnable(); }
/// <summary> /// When the teleport state is entered, simply move the player to the new location /// without any delay or other side effects. /// </summary> protected override void LocomotionTeleportOnEnterStateTeleporting() { LocomotionTeleport.DoTeleport(); }
protected override void UpdateTeleportDestination() { LocomotionTeleport.OnUpdateTeleportDestination(AimData.TargetValid, AimData.Destination, null, null); }