8 using UnityEngine.Events;
9 using System.Collections;
11 namespace Valve.VR.InteractionSystem
16 public LayerMask traceLayerMask;
17 public LayerMask floorFixupTraceLayerMask;
18 public float floorFixupMaximumTraceDistance = 1.0f;
19 public Material areaVisibleMaterial;
20 public Material areaLockedMaterial;
21 public Material areaHighlightedMaterial;
22 public Material pointVisibleMaterial;
23 public Material pointLockedMaterial;
24 public Material pointHighlightedMaterial;
25 public Transform destinationReticleTransform;
26 public Transform invalidReticleTransform;
27 public GameObject playAreaPreviewCorner;
28 public GameObject playAreaPreviewSide;
29 public Color pointerValidColor;
30 public Color pointerInvalidColor;
31 public Color pointerLockedColor;
32 public bool showPlayAreaMarker =
true;
34 public float teleportFadeTime = 0.1f;
35 public float meshFadeTime = 0.2f;
37 public float arcDistance = 10.0f;
40 public Transform onActivateObjectTransform;
41 public Transform onDeactivateObjectTransform;
42 public float activateObjectTime = 1.0f;
43 public float deactivateObjectTime = 1.0f;
45 [Header(
"Audio Sources" )]
46 public AudioSource pointerAudioSource;
47 public AudioSource loopingAudioSource;
48 public AudioSource headAudioSource;
49 public AudioSource reticleAudioSource;
52 public AudioClip teleportSound;
53 public AudioClip pointerStartSound;
54 public AudioClip pointerLoopSound;
55 public AudioClip pointerStopSound;
56 public AudioClip goodHighlightSound;
57 public AudioClip badHighlightSound;
60 public bool debugFloor =
false;
61 public bool showOffsetReticle =
false;
62 public Transform offsetReticleTransform;
63 public MeshRenderer floorDebugSphere;
64 public LineRenderer floorDebugLine;
66 private LineRenderer pointerLineRenderer;
67 private GameObject teleportPointerObject;
68 private Transform pointerStartTransform;
69 private Hand pointerHand = null;
70 private Player player = null;
73 private bool visible =
false;
78 private Vector3 pointedAtPosition;
79 private Vector3 prevPointedAtPosition;
80 private bool teleporting =
false;
81 private float currentFadeTime = 0.0f;
83 private float meshAlphaPercent = 1.0f;
84 private float pointerShowStartTime = 0.0f;
85 private float pointerHideStartTime = 0.0f;
86 private bool meshFading =
false;
87 private float fullTintAlpha;
89 private float invalidReticleMinScale = 0.2f;
90 private float invalidReticleMaxScale = 1.0f;
91 private float invalidReticleMinScaleDistance = 0.4f;
92 private float invalidReticleMaxScaleDistance = 2.0f;
93 private Vector3 invalidReticleScale = Vector3.one;
94 private Quaternion invalidReticleTargetRotation = Quaternion.identity;
96 private Transform playAreaPreviewTransform;
97 private Transform[] playAreaPreviewCorners;
98 private Transform[] playAreaPreviewSides;
100 private float loopingAudioMaxVolume = 0.0f;
102 private Coroutine hintCoroutine = null;
104 private bool originalHoverLockState =
false;
105 private Interactable originalHoveringInteractable = null;
108 private Vector3 startingFeetOffset = Vector3.zero;
109 private bool movedFeetFarEnough =
false;
130 if ( _instance == null )
132 _instance = GameObject.FindObjectOfType<
Teleport>();
145 chaperoneInfoInitializedAction = ChaperoneInfo.InitializedAction( OnChaperoneInfoInitialized );
147 pointerLineRenderer = GetComponentInChildren<LineRenderer>();
148 teleportPointerObject = pointerLineRenderer.gameObject;
150 int tintColorID = Shader.PropertyToID(
"_TintColor" );
151 fullTintAlpha = pointVisibleMaterial.GetColor( tintColorID ).a;
153 teleportArc = GetComponent<TeleportArc>();
154 teleportArc.traceLayerMask = traceLayerMask;
156 loopingAudioMaxVolume = loopingAudioSource.volume;
158 playAreaPreviewCorner.SetActive( false );
159 playAreaPreviewSide.SetActive( false );
161 float invalidReticleStartingScale = invalidReticleTransform.localScale.x;
162 invalidReticleMinScale *= invalidReticleStartingScale;
163 invalidReticleMaxScale *= invalidReticleStartingScale;
174 player = InteractionSystem.Player.instance;
176 if ( player == null )
178 Debug.LogError(
"Teleport: No Player instance found in map." );
179 Destroy( this.gameObject );
183 CheckForSpawnPoint();
185 Invoke(
"ShowTeleportHint", 5.0f );
192 chaperoneInfoInitializedAction.enabled =
true;
193 OnChaperoneInfoInitialized();
200 chaperoneInfoInitializedAction.enabled =
false;
206 private void CheckForSpawnPoint()
211 if ( teleportPoint && teleportPoint.playerSpawnPoint )
213 teleportingToMarker = teleportMarker;
222 public void HideTeleportPointer()
224 if ( pointerHand != null )
234 Hand oldPointerHand = pointerHand;
235 Hand newPointerHand = null;
237 foreach (
Hand hand
in player.hands )
241 if ( WasTeleportButtonReleased( hand ) )
243 if ( pointerHand == hand )
250 if ( WasTeleportButtonPressed( hand ) )
252 newPointerHand = hand;
257 if ( allowTeleportWhileAttached && !allowTeleportWhileAttached.teleportAllowed )
263 if ( !visible && newPointerHand != null )
266 ShowPointer( newPointerHand, oldPointerHand );
270 if ( newPointerHand == null && !IsTeleportButtonDown( pointerHand ) )
275 else if ( newPointerHand != null )
278 ShowPointer( newPointerHand, oldPointerHand );
289 UpdateTeleportColors();
292 if ( onActivateObjectTransform.gameObject.activeSelf && Time.time - pointerShowStartTime > activateObjectTime )
294 onActivateObjectTransform.gameObject.SetActive( false );
299 if ( onDeactivateObjectTransform.gameObject.activeSelf && Time.time - pointerHideStartTime > deactivateObjectTime )
301 onDeactivateObjectTransform.gameObject.SetActive( false );
308 private void UpdatePointer()
310 Vector3 pointerStart = pointerStartTransform.position;
312 Vector3 pointerDir = pointerStartTransform.forward;
313 bool hitSomething =
false;
314 bool showPlayAreaPreview =
false;
315 Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
317 Vector3 arcVelocity = pointerDir * arcDistance;
322 float dotUp = Vector3.Dot( pointerDir, Vector3.up );
323 float dotForward = Vector3.Dot( pointerDir, player.hmdTransform.forward );
324 bool pointerAtBadAngle =
false;
325 if ( ( dotForward > 0 && dotUp > 0.75f ) || ( dotForward < 0.0f && dotUp > 0.5f ) )
327 pointerAtBadAngle =
true;
332 teleportArc.SetArcData( pointerStart, arcVelocity,
true, pointerAtBadAngle );
333 if ( teleportArc.DrawArc( out hitInfo ) )
339 if ( pointerAtBadAngle )
341 hitTeleportMarker = null;
344 HighlightSelected( hitTeleportMarker );
346 if ( hitTeleportMarker != null )
348 if ( hitTeleportMarker.locked )
350 teleportArc.SetColor( pointerLockedColor );
352 pointerLineRenderer.SetColors( pointerLockedColor, pointerLockedColor );
354 pointerLineRenderer.startColor = pointerLockedColor;
355 pointerLineRenderer.endColor = pointerLockedColor;
357 destinationReticleTransform.gameObject.SetActive( false );
361 teleportArc.SetColor( pointerValidColor );
363 pointerLineRenderer.SetColors( pointerValidColor, pointerValidColor );
365 pointerLineRenderer.startColor = pointerValidColor;
366 pointerLineRenderer.endColor = pointerValidColor;
368 destinationReticleTransform.gameObject.SetActive( hitTeleportMarker.showReticle );
371 offsetReticleTransform.gameObject.SetActive( true );
373 invalidReticleTransform.gameObject.SetActive( false );
375 pointedAtTeleportMarker = hitTeleportMarker;
376 pointedAtPosition = hitInfo.point;
378 if ( showPlayAreaMarker )
382 if ( teleportArea != null && !teleportArea.locked && playAreaPreviewTransform != null )
384 Vector3 offsetToUse = playerFeetOffset;
387 if ( !movedFeetFarEnough )
389 float distanceFromStartingOffset = Vector3.Distance( playerFeetOffset, startingFeetOffset );
390 if ( distanceFromStartingOffset < 0.1f )
392 offsetToUse = startingFeetOffset;
394 else if ( distanceFromStartingOffset < 0.4f )
396 offsetToUse = Vector3.Lerp( startingFeetOffset, playerFeetOffset, ( distanceFromStartingOffset - 0.1f ) / 0.3f );
400 movedFeetFarEnough =
true;
404 playAreaPreviewTransform.position = pointedAtPosition + offsetToUse;
406 showPlayAreaPreview =
true;
410 pointerEnd = hitInfo.point;
414 destinationReticleTransform.gameObject.SetActive( false );
415 offsetReticleTransform.gameObject.SetActive( false );
417 teleportArc.SetColor( pointerInvalidColor );
419 pointerLineRenderer.SetColors( pointerInvalidColor, pointerInvalidColor );
421 pointerLineRenderer.startColor = pointerInvalidColor;
422 pointerLineRenderer.endColor = pointerInvalidColor;
424 invalidReticleTransform.gameObject.SetActive( !pointerAtBadAngle );
427 Vector3 normalToUse = hitInfo.normal;
428 float angle = Vector3.Angle( hitInfo.normal, Vector3.up );
431 normalToUse = Vector3.up;
433 invalidReticleTargetRotation = Quaternion.FromToRotation( Vector3.up, normalToUse );
434 invalidReticleTransform.rotation = Quaternion.Slerp( invalidReticleTransform.rotation, invalidReticleTargetRotation, 0.1f );
437 float distanceFromPlayer = Vector3.Distance( hitInfo.point, player.hmdTransform.position );
438 float invalidReticleCurrentScale = Util.RemapNumberClamped( distanceFromPlayer, invalidReticleMinScaleDistance, invalidReticleMaxScaleDistance, invalidReticleMinScale, invalidReticleMaxScale );
439 invalidReticleScale.x = invalidReticleCurrentScale;
440 invalidReticleScale.y = invalidReticleCurrentScale;
441 invalidReticleScale.z = invalidReticleCurrentScale;
442 invalidReticleTransform.transform.localScale = invalidReticleScale;
444 pointedAtTeleportMarker = null;
448 pointerEnd = hitInfo.point;
452 pointerEnd = teleportArc.GetArcPositionAtTime( teleportArc.arcDuration );
458 floorDebugSphere.gameObject.SetActive( false );
459 floorDebugLine.gameObject.SetActive( false );
463 if ( playAreaPreviewTransform != null )
465 playAreaPreviewTransform.gameObject.SetActive( showPlayAreaPreview );
468 if ( !showOffsetReticle )
470 offsetReticleTransform.gameObject.SetActive( false );
473 destinationReticleTransform.position = pointedAtPosition;
474 invalidReticleTransform.position = pointerEnd;
475 onActivateObjectTransform.position = pointerEnd;
476 onDeactivateObjectTransform.position = pointerEnd;
477 offsetReticleTransform.position = pointerEnd - playerFeetOffset;
479 reticleAudioSource.transform.position = pointedAtPosition;
481 pointerLineRenderer.SetPosition( 0, pointerStart );
482 pointerLineRenderer.SetPosition( 1, pointerEnd );
498 if ( teleportArea != null )
500 if ( floorFixupMaximumTraceDistance > 0.0f )
502 floorDebugSphere.gameObject.SetActive( true );
503 floorDebugLine.gameObject.SetActive( true );
505 RaycastHit raycastHit;
506 Vector3 traceDir = Vector3.down;
508 if ( Physics.Raycast( pointedAtPosition + 0.05f * traceDir, traceDir, out raycastHit, floorFixupMaximumTraceDistance, floorFixupTraceLayerMask ) )
510 floorDebugSphere.transform.position = raycastHit.point;
511 floorDebugSphere.material.color = Color.green;
513 floorDebugLine.SetColors( Color.green, Color.green );
515 floorDebugLine.startColor = Color.green;
516 floorDebugLine.endColor = Color.green;
518 floorDebugLine.SetPosition( 0, pointedAtPosition );
519 floorDebugLine.SetPosition( 1, raycastHit.point );
523 Vector3 rayEnd = pointedAtPosition + ( traceDir * floorFixupMaximumTraceDistance );
524 floorDebugSphere.transform.position = rayEnd;
525 floorDebugSphere.material.color = Color.red;
527 floorDebugLine.SetColors( Color.red, Color.red );
529 floorDebugLine.startColor = Color.red;
530 floorDebugLine.endColor = Color.red;
532 floorDebugLine.SetPosition( 0, pointedAtPosition );
533 floorDebugLine.SetPosition( 1, rayEnd );
542 private void OnChaperoneInfoInitialized()
546 if ( chaperone.initialized && chaperone.roomscale )
550 if ( playAreaPreviewTransform == null )
552 playAreaPreviewTransform =
new GameObject(
"PlayAreaPreviewTransform" ).transform;
553 playAreaPreviewTransform.parent = transform;
554 Util.ResetTransform( playAreaPreviewTransform );
556 playAreaPreviewCorner.SetActive( true );
557 playAreaPreviewCorners =
new Transform[4];
558 playAreaPreviewCorners[0] = playAreaPreviewCorner.transform;
559 playAreaPreviewCorners[1] = Instantiate( playAreaPreviewCorners[0] );
560 playAreaPreviewCorners[2] = Instantiate( playAreaPreviewCorners[0] );
561 playAreaPreviewCorners[3] = Instantiate( playAreaPreviewCorners[0] );
563 playAreaPreviewCorners[0].transform.parent = playAreaPreviewTransform;
564 playAreaPreviewCorners[1].transform.parent = playAreaPreviewTransform;
565 playAreaPreviewCorners[2].transform.parent = playAreaPreviewTransform;
566 playAreaPreviewCorners[3].transform.parent = playAreaPreviewTransform;
568 playAreaPreviewSide.SetActive( true );
569 playAreaPreviewSides =
new Transform[4];
570 playAreaPreviewSides[0] = playAreaPreviewSide.transform;
571 playAreaPreviewSides[1] = Instantiate( playAreaPreviewSides[0] );
572 playAreaPreviewSides[2] = Instantiate( playAreaPreviewSides[0] );
573 playAreaPreviewSides[3] = Instantiate( playAreaPreviewSides[0] );
575 playAreaPreviewSides[0].transform.parent = playAreaPreviewTransform;
576 playAreaPreviewSides[1].transform.parent = playAreaPreviewTransform;
577 playAreaPreviewSides[2].transform.parent = playAreaPreviewTransform;
578 playAreaPreviewSides[3].transform.parent = playAreaPreviewTransform;
581 float x = chaperone.playAreaSizeX;
582 float z = chaperone.playAreaSizeZ;
584 playAreaPreviewSides[0].localPosition =
new Vector3( 0.0f, 0.0f, 0.5f * z - 0.25f );
585 playAreaPreviewSides[1].localPosition =
new Vector3( 0.0f, 0.0f, -0.5f * z + 0.25f );
586 playAreaPreviewSides[2].localPosition =
new Vector3( 0.5f * x - 0.25f, 0.0f, 0.0f );
587 playAreaPreviewSides[3].localPosition =
new Vector3( -0.5f * x + 0.25f, 0.0f, 0.0f );
589 playAreaPreviewSides[0].localScale =
new Vector3( x - 0.5f, 1.0f, 1.0f );
590 playAreaPreviewSides[1].localScale =
new Vector3( x - 0.5f, 1.0f, 1.0f );
591 playAreaPreviewSides[2].localScale =
new Vector3( z - 0.5f, 1.0f, 1.0f );
592 playAreaPreviewSides[3].localScale =
new Vector3( z - 0.5f, 1.0f, 1.0f );
594 playAreaPreviewSides[0].localRotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f );
595 playAreaPreviewSides[1].localRotation = Quaternion.Euler( 0.0f, 180.0f, 0.0f );
596 playAreaPreviewSides[2].localRotation = Quaternion.Euler( 0.0f, 90.0f, 0.0f );
597 playAreaPreviewSides[3].localRotation = Quaternion.Euler( 0.0f, 270.0f, 0.0f );
599 playAreaPreviewCorners[0].localPosition =
new Vector3( 0.5f * x - 0.25f, 0.0f, 0.5f * z - 0.25f );
600 playAreaPreviewCorners[1].localPosition =
new Vector3( 0.5f * x - 0.25f, 0.0f, -0.5f * z + 0.25f );
601 playAreaPreviewCorners[2].localPosition =
new Vector3( -0.5f * x + 0.25f, 0.0f, -0.5f * z + 0.25f );
602 playAreaPreviewCorners[3].localPosition =
new Vector3( -0.5f * x + 0.25f, 0.0f, 0.5f * z - 0.25f );
604 playAreaPreviewCorners[0].localRotation = Quaternion.Euler( 0.0f, 0.0f, 0.0f );
605 playAreaPreviewCorners[1].localRotation = Quaternion.Euler( 0.0f, 90.0f, 0.0f );
606 playAreaPreviewCorners[2].localRotation = Quaternion.Euler( 0.0f, 180.0f, 0.0f );
607 playAreaPreviewCorners[3].localRotation = Quaternion.Euler( 0.0f, 270.0f, 0.0f );
609 playAreaPreviewTransform.gameObject.SetActive( false );
615 private void HidePointer()
619 pointerHideStartTime = Time.time;
625 if ( ShouldOverrideHoverLock() )
628 if ( originalHoverLockState ==
true )
630 pointerHand.HoverLock( originalHoveringInteractable );
634 pointerHand.HoverUnlock( null );
639 loopingAudioSource.Stop();
640 PlayAudioClip( pointerAudioSource, pointerStopSound );
642 teleportPointerObject.SetActive( false );
648 if ( teleportMarker != null && teleportMarker.markerActive && teleportMarker.gameObject != null )
650 teleportMarker.gameObject.SetActive( false );
654 destinationReticleTransform.gameObject.SetActive( false );
655 invalidReticleTransform.gameObject.SetActive( false );
656 offsetReticleTransform.gameObject.SetActive( false );
658 if ( playAreaPreviewTransform != null )
660 playAreaPreviewTransform.gameObject.SetActive( false );
663 if ( onActivateObjectTransform.gameObject.activeSelf )
665 onActivateObjectTransform.gameObject.SetActive( false );
667 onDeactivateObjectTransform.gameObject.SetActive( true );
674 private void ShowPointer(
Hand newPointerHand,
Hand oldPointerHand )
678 pointedAtTeleportMarker = null;
679 pointerShowStartTime = Time.time;
683 teleportPointerObject.SetActive( false );
688 if ( teleportMarker.markerActive && teleportMarker.ShouldActivate( player.feetPositionGuess ) )
690 teleportMarker.gameObject.SetActive( true );
691 teleportMarker.Highlight( false );
695 startingFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
696 movedFeetFarEnough =
false;
698 if ( onDeactivateObjectTransform.gameObject.activeSelf )
700 onDeactivateObjectTransform.gameObject.SetActive( false );
702 onActivateObjectTransform.gameObject.SetActive( true );
704 loopingAudioSource.clip = pointerLoopSound;
705 loopingAudioSource.loop =
true;
706 loopingAudioSource.Play();
707 loopingAudioSource.volume = 0.0f;
711 if ( oldPointerHand )
713 if ( ShouldOverrideHoverLock() )
716 if ( originalHoverLockState ==
true )
718 oldPointerHand.HoverLock( originalHoveringInteractable );
722 oldPointerHand.HoverUnlock( null );
727 pointerHand = newPointerHand;
729 if ( visible && oldPointerHand != pointerHand )
731 PlayAudioClip( pointerAudioSource, pointerStartSound );
736 pointerStartTransform = GetPointerStartTransform( pointerHand );
738 if ( pointerHand.currentAttachedObject != null )
744 originalHoverLockState = pointerHand.hoverLocked;
745 originalHoveringInteractable = pointerHand.hoveringInteractable;
747 if ( ShouldOverrideHoverLock() )
749 pointerHand.HoverLock( null );
752 pointerAudioSource.transform.SetParent( pointerStartTransform );
753 pointerAudioSource.transform.localPosition = Vector3.zero;
755 loopingAudioSource.transform.SetParent( pointerStartTransform );
756 loopingAudioSource.transform.localPosition = Vector3.zero;
762 private void UpdateTeleportColors()
764 float deltaTime = Time.time - pointerShowStartTime;
765 if ( deltaTime > meshFadeTime )
767 meshAlphaPercent = 1.0f;
772 meshAlphaPercent = Mathf.Lerp( 0.0f, 1.0f, deltaTime / meshFadeTime );
778 teleportMarker.SetAlpha( fullTintAlpha * meshAlphaPercent, meshAlphaPercent );
784 private void PlayAudioClip( AudioSource source, AudioClip clip )
792 private void PlayPointerHaptic(
bool validLocation )
794 if ( pointerHand.controller != null )
798 pointerHand.controller.TriggerHapticPulse( 800 );
802 pointerHand.controller.TriggerHapticPulse( 100 );
809 private void TryTeleportPlayer()
811 if ( visible && !teleporting )
813 if ( pointedAtTeleportMarker != null && pointedAtTeleportMarker.locked ==
false )
816 teleportingToMarker = pointedAtTeleportMarker;
817 InitiateTeleportFade();
819 CancelTeleportHint();
826 private void InitiateTeleportFade()
830 currentFadeTime = teleportFadeTime;
833 if ( teleportPoint != null && teleportPoint.teleportType == TeleportPoint.TeleportPointType.SwitchToNewScene )
835 currentFadeTime *= 3.0f;
836 Teleport.ChangeScene.Send( currentFadeTime );
839 SteamVR_Fade.Start( Color.clear, 0 );
840 SteamVR_Fade.Start( Color.black, currentFadeTime );
842 headAudioSource.transform.SetParent( player.hmdTransform );
843 headAudioSource.transform.localPosition = Vector3.zero;
844 PlayAudioClip( headAudioSource, teleportSound );
846 Invoke(
"TeleportPlayer", currentFadeTime );
851 private void TeleportPlayer()
855 Teleport.PlayerPre.Send( pointedAtTeleportMarker );
857 SteamVR_Fade.Start( Color.clear, currentFadeTime );
860 Vector3 teleportPosition = pointedAtPosition;
862 if ( teleportPoint != null )
864 teleportPosition = teleportPoint.transform.position;
867 if ( teleportPoint.teleportType == TeleportPoint.TeleportPointType.SwitchToNewScene )
869 teleportPoint.TeleportToScene();
876 if ( teleportArea != null )
878 if ( floorFixupMaximumTraceDistance > 0.0f )
880 RaycastHit raycastHit;
881 if ( Physics.Raycast( teleportPosition + 0.05f * Vector3.down, Vector3.down, out raycastHit, floorFixupMaximumTraceDistance, floorFixupTraceLayerMask ) )
883 teleportPosition = raycastHit.point;
888 if ( teleportingToMarker.ShouldMovePlayer() )
890 Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
891 player.trackingOriginTransform.position = teleportPosition + playerFeetOffset;
895 teleportingToMarker.TeleportPlayer( pointedAtPosition );
898 Teleport.Player.Send( pointedAtTeleportMarker );
905 if ( pointedAtTeleportMarker != hitTeleportMarker )
907 if ( pointedAtTeleportMarker != null )
909 pointedAtTeleportMarker.Highlight( false );
912 if ( hitTeleportMarker != null )
914 hitTeleportMarker.Highlight( true );
916 prevPointedAtPosition = pointedAtPosition;
917 PlayPointerHaptic( !hitTeleportMarker.locked );
919 PlayAudioClip( reticleAudioSource, goodHighlightSound );
921 loopingAudioSource.volume = loopingAudioMaxVolume;
923 else if ( pointedAtTeleportMarker != null )
925 PlayAudioClip( reticleAudioSource, badHighlightSound );
927 loopingAudioSource.volume = 0.0f;
930 else if ( hitTeleportMarker != null )
932 if ( Vector3.Distance( prevPointedAtPosition, pointedAtPosition ) > 1.0f )
934 prevPointedAtPosition = pointedAtPosition;
935 PlayPointerHaptic( !hitTeleportMarker.locked );
942 public void ShowTeleportHint()
944 CancelTeleportHint();
946 hintCoroutine = StartCoroutine( TeleportHintCoroutine() );
951 public void CancelTeleportHint()
953 if ( hintCoroutine != null )
955 foreach (
Hand hand
in player.hands )
957 ControllerButtonHints.HideTextHint( hand, EVRButtonId.k_EButton_SteamVR_Touchpad );
960 StopCoroutine( hintCoroutine );
961 hintCoroutine = null;
964 CancelInvoke(
"ShowTeleportHint" );
969 private IEnumerator TeleportHintCoroutine()
971 float prevBreakTime = Time.time;
972 float prevHapticPulseTime = Time.time;
979 foreach (
Hand hand
in player.hands )
981 bool showHint = IsEligibleForTeleport( hand );
982 bool isShowingHint = !string.IsNullOrEmpty( ControllerButtonHints.GetActiveHintText( hand, EVRButtonId.k_EButton_SteamVR_Touchpad ) );
985 if ( !isShowingHint )
987 ControllerButtonHints.ShowTextHint( hand, EVRButtonId.k_EButton_SteamVR_Touchpad,
"Teleport" );
988 prevBreakTime = Time.time;
989 prevHapticPulseTime = Time.time;
992 if ( Time.time > prevHapticPulseTime + 0.05f )
997 hand.controller.TriggerHapticPulse( 500 );
1000 else if ( !showHint && isShowingHint )
1002 ControllerButtonHints.HideTextHint( hand, EVRButtonId.k_EButton_SteamVR_Touchpad );
1006 if ( Time.time > prevBreakTime + 3.0f )
1009 yield
return new WaitForSeconds( 3.0f );
1011 prevBreakTime = Time.time;
1016 prevHapticPulseTime = Time.time;
1025 public bool IsEligibleForTeleport(
Hand hand )
1032 if ( !hand.gameObject.activeInHierarchy )
1037 if ( hand.hoveringInteractable != null )
1042 if ( hand.noSteamVRFallbackCamera == null )
1044 if ( hand.controller == null )
1050 if ( hand.currentAttachedObject != null )
1054 if ( allowTeleportWhileAttachedToHand != null && allowTeleportWhileAttachedToHand.teleportAllowed ==
true )
1070 private bool ShouldOverrideHoverLock()
1072 if ( !allowTeleportWhileAttached || allowTeleportWhileAttached.overrideHoverLock )
1082 private bool WasTeleportButtonReleased(
Hand hand )
1084 if ( IsEligibleForTeleport( hand ) )
1086 if ( hand.noSteamVRFallbackCamera != null )
1088 return Input.GetKeyUp( KeyCode.T );
1092 return hand.controller.GetPressUp( SteamVR_Controller.ButtonMask.Touchpad );
1101 private bool IsTeleportButtonDown(
Hand hand )
1103 if ( IsEligibleForTeleport( hand ) )
1105 if ( hand.noSteamVRFallbackCamera != null )
1107 return Input.GetKey( KeyCode.T );
1111 return hand.controller.GetPress( SteamVR_Controller.ButtonMask.Touchpad );
1120 private bool WasTeleportButtonPressed(
Hand hand )
1122 if ( IsEligibleForTeleport( hand ) )
1124 if ( hand.noSteamVRFallbackCamera != null )
1126 return Input.GetKeyDown( KeyCode.T );
1130 return hand.controller.GetPressDown( SteamVR_Controller.ButtonMask.Touchpad );
1139 private Transform GetPointerStartTransform(
Hand hand )
1141 if ( hand.noSteamVRFallbackCamera != null )
1143 return hand.noSteamVRFallbackCamera.transform;
1147 return pointerHand.GetAttachmentTransform(
"Attach_ControllerTip" );