You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			183 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C#
		
	
			
		
		
	
	
			183 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			C#
		
	
// 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);
 | 
						|
        }
 | 
						|
    }
 | 
						|
} |