SnapTurn.cs 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // Copyright (c) Valve Corporation, All rights reserved. ======================================================================================================
  2. using UnityEngine;
  3. using System.Collections;
  4. namespace Valve.VR.InteractionSystem
  5. {
  6. //-----------------------------------------------------------------------------
  7. public class SnapTurn : MonoBehaviour
  8. {
  9. public float snapAngle = 90.0f;
  10. public bool showTurnAnimation = true;
  11. public AudioSource snapTurnSource;
  12. public AudioClip rotateSound;
  13. public GameObject rotateRightFX;
  14. public GameObject rotateLeftFX;
  15. public SteamVR_Action_Boolean snapLeftAction = SteamVR_Input.GetBooleanAction("SnapTurnLeft");
  16. public SteamVR_Action_Boolean snapRightAction = SteamVR_Input.GetBooleanAction("SnapTurnRight");
  17. public bool fadeScreen = true;
  18. public float fadeTime = 0.1f;
  19. public Color screenFadeColor = Color.black;
  20. public float distanceFromFace = 1.3f;
  21. public Vector3 additionalOffset = new Vector3(0, -0.3f, 0);
  22. public static float teleportLastActiveTime;
  23. private bool canRotate = true;
  24. public float canTurnEverySeconds = 0.4f;
  25. private void Start()
  26. {
  27. AllOff();
  28. }
  29. private void AllOff()
  30. {
  31. if (rotateLeftFX != null)
  32. rotateLeftFX.SetActive(false);
  33. if (rotateRightFX != null)
  34. rotateRightFX.SetActive(false);
  35. }
  36. private void Update()
  37. {
  38. Player player = Player.instance;
  39. if (canRotate && snapLeftAction != null && snapRightAction != null && snapLeftAction.activeBinding && snapRightAction.activeBinding)
  40. {
  41. //only allow snap turning after a quarter second after the last teleport
  42. if (Time.time < (teleportLastActiveTime + canTurnEverySeconds))
  43. return;
  44. // only allow snap turning when not holding something
  45. bool rightHandValid = player.rightHand.currentAttachedObject == null ||
  46. (player.rightHand.currentAttachedObject != null
  47. && player.rightHand.currentAttachedTeleportManager != null
  48. && player.rightHand.currentAttachedTeleportManager.teleportAllowed);
  49. bool leftHandValid = player.leftHand.currentAttachedObject == null ||
  50. (player.leftHand.currentAttachedObject != null
  51. && player.leftHand.currentAttachedTeleportManager != null
  52. && player.leftHand.currentAttachedTeleportManager.teleportAllowed);
  53. bool leftHandTurnLeft = snapLeftAction.GetStateDown(SteamVR_Input_Sources.LeftHand) && leftHandValid;
  54. bool rightHandTurnLeft = snapLeftAction.GetStateDown(SteamVR_Input_Sources.RightHand) && rightHandValid;
  55. bool leftHandTurnRight = snapRightAction.GetStateDown(SteamVR_Input_Sources.LeftHand) && leftHandValid;
  56. bool rightHandTurnRight = snapRightAction.GetStateDown(SteamVR_Input_Sources.RightHand) && rightHandValid;
  57. if (leftHandTurnLeft || rightHandTurnLeft)
  58. {
  59. RotatePlayer(-snapAngle);
  60. }
  61. else if (leftHandTurnRight || rightHandTurnRight)
  62. {
  63. RotatePlayer(snapAngle);
  64. }
  65. }
  66. }
  67. private Coroutine rotateCoroutine;
  68. public void RotatePlayer(float angle)
  69. {
  70. if (rotateCoroutine != null)
  71. {
  72. StopCoroutine(rotateCoroutine);
  73. AllOff();
  74. }
  75. rotateCoroutine = StartCoroutine(DoRotatePlayer(angle));
  76. }
  77. //-----------------------------------------------------
  78. private IEnumerator DoRotatePlayer(float angle)
  79. {
  80. Player player = Player.instance;
  81. canRotate = false;
  82. snapTurnSource.panStereo = angle / 90;
  83. snapTurnSource.PlayOneShot(rotateSound);
  84. if (fadeScreen)
  85. {
  86. SteamVR_Fade.Start(Color.clear, 0);
  87. Color tColor = screenFadeColor;
  88. tColor = tColor.linear * 0.6f;
  89. SteamVR_Fade.Start(tColor, fadeTime);
  90. }
  91. yield return new WaitForSeconds(fadeTime);
  92. Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
  93. player.trackingOriginTransform.position -= playerFeetOffset;
  94. player.transform.Rotate(Vector3.up, angle);
  95. playerFeetOffset = Quaternion.Euler(0.0f, angle, 0.0f) * playerFeetOffset;
  96. player.trackingOriginTransform.position += playerFeetOffset;
  97. GameObject fx = angle > 0 ? rotateRightFX : rotateLeftFX;
  98. if (showTurnAnimation)
  99. ShowRotateFX(fx);
  100. if (fadeScreen)
  101. {
  102. SteamVR_Fade.Start(Color.clear, fadeTime);
  103. }
  104. float startTime = Time.time;
  105. float endTime = startTime + canTurnEverySeconds;
  106. while (Time.time <= endTime)
  107. {
  108. yield return null;
  109. UpdateOrientation(fx);
  110. };
  111. fx.SetActive(false);
  112. canRotate = true;
  113. }
  114. void ShowRotateFX(GameObject fx)
  115. {
  116. if (fx == null)
  117. return;
  118. fx.SetActive(false);
  119. UpdateOrientation(fx);
  120. fx.SetActive(true);
  121. UpdateOrientation(fx);
  122. }
  123. private void UpdateOrientation(GameObject fx)
  124. {
  125. Player player = Player.instance;
  126. //position fx in front of face
  127. this.transform.position = player.hmdTransform.position + (player.hmdTransform.forward * distanceFromFace);
  128. this.transform.rotation = Quaternion.LookRotation(player.hmdTransform.position - this.transform.position, Vector3.up);
  129. this.transform.Translate(additionalOffset, Space.Self);
  130. this.transform.rotation = Quaternion.LookRotation(player.hmdTransform.position - this.transform.position, Vector3.up);
  131. }
  132. }
  133. }