123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 |
- // Copyright (c) Valve Corporation, All rights reserved. ======================================================================================================
- using UnityEngine;
- using System.Collections;
- namespace Valve.VR.InteractionSystem
- {
- //-----------------------------------------------------------------------------
- public class SnapTurn : MonoBehaviour
- {
- public float snapAngle = 90.0f;
- public bool showTurnAnimation = true;
- public AudioSource snapTurnSource;
- public AudioClip rotateSound;
- public GameObject rotateRightFX;
- public GameObject rotateLeftFX;
- public SteamVR_Action_Boolean snapLeftAction = SteamVR_Input.GetBooleanAction("SnapTurnLeft");
- public SteamVR_Action_Boolean snapRightAction = SteamVR_Input.GetBooleanAction("SnapTurnRight");
- public bool fadeScreen = true;
- public float fadeTime = 0.1f;
- public Color screenFadeColor = Color.black;
- public float distanceFromFace = 1.3f;
- public Vector3 additionalOffset = new Vector3(0, -0.3f, 0);
- public static float teleportLastActiveTime;
- private bool canRotate = true;
- public float canTurnEverySeconds = 0.4f;
- private void Start()
- {
- AllOff();
- }
- private void AllOff()
- {
- if (rotateLeftFX != null)
- rotateLeftFX.SetActive(false);
- if (rotateRightFX != null)
- rotateRightFX.SetActive(false);
- }
- private void Update()
- {
- Player player = Player.instance;
- if (canRotate && snapLeftAction != null && snapRightAction != null && snapLeftAction.activeBinding && snapRightAction.activeBinding)
- {
- //only allow snap turning after a quarter second after the last teleport
- if (Time.time < (teleportLastActiveTime + canTurnEverySeconds))
- return;
- // only allow snap turning when not holding something
- bool rightHandValid = player.rightHand.currentAttachedObject == null ||
- (player.rightHand.currentAttachedObject != null
- && player.rightHand.currentAttachedTeleportManager != null
- && player.rightHand.currentAttachedTeleportManager.teleportAllowed);
- bool leftHandValid = player.leftHand.currentAttachedObject == null ||
- (player.leftHand.currentAttachedObject != null
- && player.leftHand.currentAttachedTeleportManager != null
- && player.leftHand.currentAttachedTeleportManager.teleportAllowed);
- bool leftHandTurnLeft = snapLeftAction.GetStateDown(SteamVR_Input_Sources.LeftHand) && leftHandValid;
- bool rightHandTurnLeft = snapLeftAction.GetStateDown(SteamVR_Input_Sources.RightHand) && rightHandValid;
- bool leftHandTurnRight = snapRightAction.GetStateDown(SteamVR_Input_Sources.LeftHand) && leftHandValid;
- bool rightHandTurnRight = snapRightAction.GetStateDown(SteamVR_Input_Sources.RightHand) && rightHandValid;
- if (leftHandTurnLeft || rightHandTurnLeft)
- {
- RotatePlayer(-snapAngle);
- }
- else if (leftHandTurnRight || rightHandTurnRight)
- {
- RotatePlayer(snapAngle);
- }
- }
- }
- private Coroutine rotateCoroutine;
- public void RotatePlayer(float angle)
- {
- if (rotateCoroutine != null)
- {
- StopCoroutine(rotateCoroutine);
- AllOff();
- }
- rotateCoroutine = StartCoroutine(DoRotatePlayer(angle));
- }
- //-----------------------------------------------------
- private IEnumerator DoRotatePlayer(float angle)
- {
- Player player = Player.instance;
- canRotate = false;
- snapTurnSource.panStereo = angle / 90;
- snapTurnSource.PlayOneShot(rotateSound);
- if (fadeScreen)
- {
- SteamVR_Fade.Start(Color.clear, 0);
- Color tColor = screenFadeColor;
- tColor = tColor.linear * 0.6f;
- SteamVR_Fade.Start(tColor, fadeTime);
- }
- yield return new WaitForSeconds(fadeTime);
- Vector3 playerFeetOffset = player.trackingOriginTransform.position - player.feetPositionGuess;
- player.trackingOriginTransform.position -= playerFeetOffset;
- player.transform.Rotate(Vector3.up, angle);
- playerFeetOffset = Quaternion.Euler(0.0f, angle, 0.0f) * playerFeetOffset;
- player.trackingOriginTransform.position += playerFeetOffset;
- GameObject fx = angle > 0 ? rotateRightFX : rotateLeftFX;
- if (showTurnAnimation)
- ShowRotateFX(fx);
- if (fadeScreen)
- {
- SteamVR_Fade.Start(Color.clear, fadeTime);
- }
- float startTime = Time.time;
- float endTime = startTime + canTurnEverySeconds;
- while (Time.time <= endTime)
- {
- yield return null;
- UpdateOrientation(fx);
- };
- fx.SetActive(false);
- canRotate = true;
- }
- void ShowRotateFX(GameObject fx)
- {
- if (fx == null)
- return;
- fx.SetActive(false);
- UpdateOrientation(fx);
- fx.SetActive(true);
- UpdateOrientation(fx);
- }
- private void UpdateOrientation(GameObject fx)
- {
- Player player = Player.instance;
- //position fx in front of face
- this.transform.position = player.hmdTransform.position + (player.hmdTransform.forward * distanceFromFace);
- this.transform.rotation = Quaternion.LookRotation(player.hmdTransform.position - this.transform.position, Vector3.up);
- this.transform.Translate(additionalOffset, Space.Self);
- this.transform.rotation = Quaternion.LookRotation(player.hmdTransform.position - this.transform.position, Vector3.up);
- }
- }
- }
|