|
5 | 5 | using Microsoft.MixedReality.Toolkit.Physics;
|
6 | 6 | using Microsoft.MixedReality.Toolkit.Utilities;
|
7 | 7 | using System;
|
| 8 | +using System.Runtime.CompilerServices; |
8 | 9 | using Unity.Profiling;
|
9 | 10 | using UnityEngine;
|
10 | 11 | using UnityPhysics = UnityEngine.Physics;
|
11 | 12 |
|
| 13 | +[assembly: InternalsVisibleTo("Microsoft.MixedReality.Toolkit.Tests.PlayModeTests")] |
12 | 14 | namespace Microsoft.MixedReality.Toolkit.Teleport
|
13 | 15 | {
|
14 | 16 | /// <summary>
|
@@ -85,7 +87,20 @@ public bool TeleportHotSpotCursorVisibility
|
85 | 87 |
|
86 | 88 | [SerializeField]
|
87 | 89 | [Tooltip("The distance to move the camera when the strafe is activated")]
|
88 |
| - private float strafeAmount = 0.25f; |
| 90 | + internal float strafeAmount = 0.25f; |
| 91 | + |
| 92 | + [SerializeField] |
| 93 | + [Tooltip("Whether or not a strafe checks that there is a floor beneath the user's origin on strafe")] |
| 94 | + internal bool checkForFloorOnStrafe = false; |
| 95 | + |
| 96 | + [SerializeField] |
| 97 | + [Tooltip("Whether or not the user's y-position can move during a strafe")] |
| 98 | + internal bool adjustHeightOnStrafe = false; |
| 99 | + |
| 100 | + |
| 101 | + [SerializeField] |
| 102 | + [Tooltip("The detection range for a floor on strafe, as well as the max amount that a user's y-position can change on strafe")] |
| 103 | + internal float maxHeightChangeOnStrafe = 0.5f; |
89 | 104 |
|
90 | 105 | [SerializeField]
|
91 | 106 | [Range(0f, 1f)]
|
@@ -231,6 +246,58 @@ protected Gradient GetLineGradient(TeleportSurfaceResult targetResult)
|
231 | 246 | }
|
232 | 247 | }
|
233 | 248 |
|
| 249 | + /// <summary> |
| 250 | + /// check if a backstrafe is possible on a valid platform regarding the possible strafe height given |
| 251 | + /// </summary> |
| 252 | + /// <param name="newPosition">the new position relative to backstrafe position</param> |
| 253 | + /// <param name="hitStrafePosition">actual position the strafe raycast hits</param> |
| 254 | + /// <returns>if there is a valid layer one can backstrafe on</returns> |
| 255 | + internal bool CheckPossibleBackStep(Vector3 newPosition, out Vector3 hitStrafePosition) |
| 256 | + { |
| 257 | + var raycastProvider = CoreServices.InputSystem.RaycastProvider; |
| 258 | + Vector3 strafeOrigin = new Vector3(newPosition.x, MixedRealityPlayspace.Position.y + maxHeightChangeOnStrafe, newPosition.z); |
| 259 | + Vector3 strafeTerminus = strafeOrigin + (Vector3.down * maxHeightChangeOnStrafe * 2f); |
| 260 | + |
| 261 | + RayStep rayStep = new RayStep(strafeOrigin, strafeTerminus); |
| 262 | + LayerMask[] layerMasks = new LayerMask[] { ValidLayers }; |
| 263 | + |
| 264 | + // check are we hiting a floor plane or step above the current MixedRealityPlayspace.Position |
| 265 | + if (!raycastProvider.IsNull() && raycastProvider.Raycast(rayStep, layerMasks, false, out var hitInfo)) |
| 266 | + { |
| 267 | + hitStrafePosition = hitInfo.point; |
| 268 | + return true; |
| 269 | + } |
| 270 | + |
| 271 | + hitStrafePosition = Vector3.zero; |
| 272 | + return false; |
| 273 | + } |
| 274 | + |
| 275 | + /// <summary> |
| 276 | + /// Performs a strafe in the opposite direction of the camera's forward direction |
| 277 | + /// </summary> |
| 278 | + internal void PerformStrafe() |
| 279 | + { |
| 280 | + canMove = false; |
| 281 | + var height = MixedRealityPlayspace.Position.y; |
| 282 | + var newPosition = -CameraCache.Main.transform.forward * strafeAmount + MixedRealityPlayspace.Position; |
| 283 | + |
| 284 | + newPosition.y = height; |
| 285 | + bool isValidStrafe = true; |
| 286 | + if (checkForFloorOnStrafe) |
| 287 | + { |
| 288 | + isValidStrafe = CheckPossibleBackStep(newPosition, out var strafeHitPosition); |
| 289 | + if (adjustHeightOnStrafe) |
| 290 | + { |
| 291 | + newPosition = strafeHitPosition; |
| 292 | + } |
| 293 | + } |
| 294 | + |
| 295 | + if (isValidStrafe) |
| 296 | + { |
| 297 | + MixedRealityPlayspace.Position = newPosition; |
| 298 | + } |
| 299 | + } |
| 300 | + |
234 | 301 | #region IMixedRealityPointer Implementation
|
235 | 302 |
|
236 | 303 | /// <inheritdoc />
|
@@ -469,11 +536,7 @@ public override void OnInputChanged(InputEventData<Vector2> eventData)
|
469 | 536 | // Check to make sure we're still under our activation threshold.
|
470 | 537 | if (offsetStrafeAngle > 0 && offsetStrafeAngle <= backStrafeActivationAngle)
|
471 | 538 | {
|
472 |
| - canMove = false; |
473 |
| - var height = MixedRealityPlayspace.Position.y; |
474 |
| - var newPosition = -CameraCache.Main.transform.forward * strafeAmount + MixedRealityPlayspace.Position; |
475 |
| - newPosition.y = height; |
476 |
| - MixedRealityPlayspace.Position = newPosition; |
| 539 | + PerformStrafe(); |
477 | 540 | }
|
478 | 541 | }
|
479 | 542 | }
|
|
0 commit comments