VRTrackingReset
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();
}
}
}
VREyeRaycaster
using 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;
}
}
}