using UnityEngine; using UnityEngine.VR;
namespace VRStandardAssets.Utils { // This class simply insures the head tracking behaves correctly when the application is paused. 该类简单地保证了当应用程序暂停时,头跟踪行为正确。 public class VRTrackingReset : MonoBehaviour { private void OnApplicationPause(bool pauseStatus) { InputTracking.Recenter(); } } }
VREyeRaycasterusing System; using UnityEngine;
namespace VRStandardAssets.Utils { // In order to interact with objects in the scene为了与场景中的对象交互 // this class casts a ray into the scene and if it finds这个类向场景投射了一个光线,如果它发现了。 // a VRInteractiveItem it exposes it for other classes to use.它为其他类公开使用它。 // This script should be generally be placed on the camera.这个脚本一般应该放在相机上。 public class VREyeRaycaster : MonoBehaviour { public event Action OnRaycasthit; // This event is called every frame that the user’s gaze is over a collider.这个事件被称为用户注视的每一帧在对撞机上
[SerializeField] private Transform m_Camera; [SerializeField] private LayerMask m_ExclusionLayers; // Layers to exclude from the raycast.层从RayCasp中排除。 [SerializeField] private Reticle m_Reticle; // The reticle, if applicable.光罩,如果适用的话。 [SerializeField] private VRInput m_VrInput; // Used to call input based events on the current VRInteractiveItem.用于调用当前VRATICATIVE项上的基于输入的事件。 [SerializeField] private bool m_ShowDebugRay; // Optionally show the debug ray.可选地显示调试光线 [SerializeField] private float m_DebugRayLength = 5f; // Debug ray length.调试光线长度 [SerializeField] private float m_DebugRayDuration = 1f; // How long the Debug ray will remain visible.调试光线将保持多长时间可见。 [SerializeField] private float m_RayLength = 500f; // How far into the scene the ray is cast.光线投射到这个场景有多远。 private VRInteractiveItem m_CurrentInteractible; //The current interactive item当前交互项 private VRInteractiveItem m_LastInteractible; //The last interactive item最后一个交互项 // Utility for other classes to get the current interactive item用于获取当前交互项的其他类的实用工具 public VRInteractiveItem CurrentInteractible { get { return m_CurrentInteractible; } } private void OnEnable() { m_VrInput.OnClick += HandleClick; m_VrInput.OnDoubleClick += HandleDoubleClick; m_VrInput.OnUp += HandleUp; m_VrInput.OnDown += HandleDown; } private void OnDisable () { m_VrInput.OnClick -= HandleClick; m_VrInput.OnDoubleClick -= HandleDoubleClick; m_VrInput.OnUp -= HandleUp; m_VrInput.OnDown -= HandleDown; } private void Update() { EyeRaycast(); } private void EyeRaycast() { // Show the debug ray if required如果需要,请显示调试光线 if (m_ShowDebugRay) { Debug.DrawRay(m_Camera.position, m_Camera.forward * m_DebugRayLength, Color.blue, m_DebugRayDuration); } // Create a ray that points forwards from the camera.创建一个从相机指向的光线。 Ray ray = new Ray(m_Camera.position, m_Camera.forward); RaycastHit hit; // Do the raycast forweards to see if we hit an interactive item RayStube是否磨损,看看我们是否碰到了一个交互式项目 if (Physics.Raycast(ray, out hit, m_RayLength, ~m_ExclusionLayers)) { VRInteractiveItem interactible = hit.collider.GetComponent<VRInteractiveItem>(); //attempt to get the VRInteractiveItem on the hit object尝试获取命中对象的vrIcTrimeIt目 m_CurrentInteractible = interactible; // If we hit an interactive item and it's not the same as the last interactive item, then call Over如果我们碰到了一个交互项,它和上次的交互项不一样,然后调用 if (interactible && interactible != m_LastInteractible) interactible.Over(); // Deactive the last interactive item 取消最后一个交互项 if (interactible != m_LastInteractible) DeactiveLastInteractible(); m_LastInteractible = interactible; // Something was hit, set at the hit position.一些东西被击中,设置在击中位置 if (m_Reticle) m_Reticle.SetPosition(hit); if (OnRaycasthit != null) OnRaycasthit(hit); } else { // Nothing was hit, deactive the last interactive item.没有任何东西被击中,最后一个交互项无效 DeactiveLastInteractible(); m_CurrentInteractible = null; // Position the reticle at default distance.将光罩置于默认距离 if (m_Reticle) m_Reticle.SetPosition(); } } private void DeactiveLastInteractible() { if (m_LastInteractible == null) return; m_LastInteractible.Out(); m_LastInteractible = null; } private void HandleUp() { if (m_CurrentInteractible != null) m_CurrentInteractible.Up(); } private void HandleDown() { if (m_CurrentInteractible != null) m_CurrentInteractible.Down(); } private void HandleClick() { if (m_CurrentInteractible != null) m_CurrentInteractible.Click(); } private void HandleDoubleClick() { if (m_CurrentInteractible != null) m_CurrentInteractible.DoubleClick(); } }} VRInput
using System; using UnityEngine;
namespace VRStandardAssets.Utils { // This class encapsulates all the input required for most VR games. // It has events that can be subscribed to by classes that need specific input. // This class must exist in every scene and so can be attached to the main // camera for ease. public class VRInput : MonoBehaviour { //Swipe directions public enum SwipeDirection { NONE, UP, DOWN, LEFT, RIGHT };
public event Action<SwipeDirection> OnSwipe; // Called every frame passing in the swipe, including if there is no swipe.调用每一帧在掠过,包括如果没有滑动。 public event Action OnClick; // Called when Fire1 is released and it's not a double click.当Fiel1被释放而不是双击时调用 public event Action OnDown; // Called when Fire1 is pressed.当FIL1被按下时调用 public event Action OnUp; // Called when Fire1 is released.在释放FIL1时调用 public event Action OnDoubleClick; // Called when a double click is detected.当检测到双击时调用 public event Action OnCancel; // Called when Cancel is pressed.当取消取消时调用 [SerializeField] private float m_DoubleClickTime = 0.3f; //The max time allowed between double clicks双点击允许的最大时间 [SerializeField] private float m_SwipeWidth = 0.3f; //The width of a swipe滑动的宽度 private Vector2 m_MouseDownPosition; // The screen position of the mouse when Fire1 is pressed.当FIL1被按下时,鼠标的屏幕位置 private Vector2 m_MouseUpPosition; // The screen position of the mouse when Fire1 is released.释放FIL1时鼠标的屏幕位置 private float m_LastMouseUpTime; // The time when Fire1 was last released.上次发布Fiel1的时间 private float m_LastHorizontalValue; // The previous value of the horizontal axis used to detect keyboard swipes.用于检测键盘擦拭的水平轴的先前值 private float m_LastVerticalValue; // The previous value of the vertical axis used to detect keyboard swipes.用于检测键盘擦拭的垂直轴的先前值 public float DoubleClickTime{ get { return m_DoubleClickTime; } } private void Update() { CheckInput(); } private void CheckInput() { // Set the default swipe to be none. SwipeDirection swipe = SwipeDirection.NONE; if (Input.GetButtonDown("Fire1")) { // When Fire1 is pressed record the position of the mouse. m_MouseDownPosition = new Vector2(Input.mousePosition.x, Input.mousePosition.y); // If anything has subscribed to OnDown call it. if (OnDown != null) OnDown(); } // This if statement is to gather information about the mouse when the button is up. if (Input.GetButtonUp ("Fire1")) { // When Fire1 is released record the position of the mouse. m_MouseUpPosition = new Vector2 (Input.mousePosition.x, Input.mousePosition.y); // Detect the direction between the mouse positions when Fire1 is pressed and released. swipe = DetectSwipe (); } // If there was no swipe this frame from the mouse, check for a keyboard swipe. if (swipe == SwipeDirection.NONE) swipe = DetectKeyboardEmulatedSwipe(); // If there are any subscribers to OnSwipe call it passing in the detected swipe. if (OnSwipe != null) OnSwipe(swipe); // This if statement is to trigger events based on the information gathered before. if(Input.GetButtonUp ("Fire1")) { // If anything has subscribed to OnUp call it. if (OnUp != null) OnUp(); // If the time between the last release of Fire1 and now is less // than the allowed double click time then it's a double click. if (Time.time - m_LastMouseUpTime < m_DoubleClickTime) { // If anything has subscribed to OnDoubleClick call it. if (OnDoubleClick != null) OnDoubleClick(); } else { // If it's not a double click, it's a single click. // If anything has subscribed to OnClick call it. if (OnClick != null) OnClick(); } // Record the time when Fire1 is released. m_LastMouseUpTime = Time.time; } // If the Cancel button is pressed and there are subscribers to OnCancel call it. if (Input.GetButtonDown("Cancel")) { if (OnCancel != null) OnCancel(); } } private SwipeDirection DetectSwipe () { // Get the direction from the mouse position when Fire1 is pressed to when it is released. Vector2 swipeData = (m_MouseUpPosition - m_MouseDownPosition).normalized; // If the direction of the swipe has a small width it is vertical. bool swipeIsVertical = Mathf.Abs (swipeData.x) < m_SwipeWidth; // If the direction of the swipe has a small height it is horizontal. bool swipeIsHorizontal = Mathf.Abs(swipeData.y) < m_SwipeWidth; // If the swipe has a positive y component and is vertical the swipe is up. if (swipeData.y > 0f && swipeIsVertical) return SwipeDirection.UP; // If the swipe has a negative y component and is vertical the swipe is down. if (swipeData.y < 0f && swipeIsVertical) return SwipeDirection.DOWN; // If the swipe has a positive x component and is horizontal the swipe is right. if (swipeData.x > 0f && swipeIsHorizontal) return SwipeDirection.RIGHT; // If the swipe has a negative x component and is vertical the swipe is left. if (swipeData.x < 0f && swipeIsHorizontal) return SwipeDirection.LEFT; // If the swipe meets none of these requirements there is no swipe. return SwipeDirection.NONE; } private SwipeDirection DetectKeyboardEmulatedSwipe () { // Store the values for Horizontal and Vertical axes. float horizontal = Input.GetAxis ("Horizontal"); float vertical = Input.GetAxis ("Vertical"); // Store whether there was horizontal or vertical input before. bool noHorizontalInputPreviously = Mathf.Abs (m_LastHorizontalValue) < float.Epsilon; bool noVerticalInputPreviously = Mathf.Abs(m_LastVerticalValue) < float.Epsilon; // The last horizontal values are now the current ones. m_LastHorizontalValue = horizontal; m_LastVerticalValue = vertical; // If there is positive vertical input now and previously there wasn't the swipe is up. if (vertical > 0f && noVerticalInputPreviously) return SwipeDirection.UP; // If there is negative vertical input now and previously there wasn't the swipe is down. if (vertical < 0f && noVerticalInputPreviously) return SwipeDirection.DOWN; // If there is positive horizontal input now and previously there wasn't the swipe is right. if (horizontal > 0f && noHorizontalInputPreviously) return SwipeDirection.RIGHT; // If there is negative horizontal input now and previously there wasn't the swipe is left. if (horizontal < 0f && noHorizontalInputPreviously) return SwipeDirection.LEFT; // If the swipe meets none of these requirements there is no swipe. return SwipeDirection.NONE; } private void OnDestroy() { // Ensure that all events are unsubscribed when this is destroyed. OnSwipe = null; OnClick = null; OnDoubleClick = null; OnDown = null; OnUp = null; } }}