|
|
|
using UnityEngine;
|
using UnityEngine.XR.Interaction.Toolkit;
|
using UnityEngine.XR;
|
|
using UnityEngine.Events;
|
|
|
public class VRInputManager : Singleton<VRInputManager>
|
{
|
|
/// <summary>
|
/// 왼손, 오른손 컨트롤러 변수
|
/// </summary>
|
private InputDevice rightHandDevice;
|
private InputDevice leftHandDevice;
|
|
/// <summary>
|
/// 왼손, 오른손 물체 상호작용 관련 변수
|
/// </summary>
|
public XRRayInteractor leftRay;
|
public XRRayInteractor rightRay;
|
|
|
|
|
/// <summary>
|
/// 메뉴 ui 오브젝트
|
/// </summary>
|
public GameObject Menu;
|
|
|
//[SerializeField] private XRRayInteractor rayInteractor;
|
//[SerializeField] private TeleportationProvider provider;
|
//private InputAction _thumbstick;
|
//private bool _isActive;
|
//List<InputDevice> inputDevices = new List<InputDevice>();
|
|
|
|
public bool trackPadIsTouch = false;
|
private bool trackPadIsRunning = false;
|
private bool leftTrackPadPressed = false;
|
private bool rightTrackPadPressed = false;
|
private bool primary2DAxisLeftSelect = false;
|
private bool primary2DAxisRightSelect = false;
|
private bool primary2DAxisUpSelect = false;
|
private bool primary2DAxisDownSelect = false;
|
private bool primary2DAxisLeftUpTouch = false;
|
private bool primary2DAxisRightUpTouch = false;
|
private Vector2 leftTrackPos = Vector2.zero;
|
private Vector2 rightTrackPos = Vector2.zero;
|
|
|
private bool triggerIsRunning = false;
|
private bool leftTriggerPressed = false;
|
private bool rightTriggerPressed = false;
|
|
|
public bool gripIsRunning = false;
|
private bool leftGripPressed = false;
|
private bool rightGripPressed = false;
|
|
|
|
private bool menuIsRunning = false;
|
private bool leftMenuPressed = false;
|
private bool rightMenuPressed = false;
|
|
|
/// <summary>
|
/// 각 버튼별 동작 시 이벤트 모음
|
/// </summary>
|
public UnityEvent Primary2DAxisUpSelect;
|
public UnityEvent Primary2DAxisUpSelectExit;
|
public UnityEvent Primary2DAxisDownSelect;
|
public UnityEvent Primary2DAxisDownSelectExit;
|
public UnityEvent Primary2DAxisLeftSelect;
|
public UnityEvent Primary2DAxisLeftSelectExit;
|
public UnityEvent Primary2DAxisRightSelect;
|
public UnityEvent Primary2DAxisRightSelectExit;
|
public UnityEvent TriggerSelect;
|
public UnityEvent TriggerSelectExit;
|
|
|
|
public override void Awake()
|
{
|
|
}
|
|
void Start()
|
{
|
if (Menu != null)
|
{
|
Menu.SetActive(false);
|
}
|
|
|
}
|
|
|
|
// Update is called once per frame
|
void Update()
|
{
|
GetDevice();
|
OnTrigger(leftHandDevice, rightHandDevice);
|
OnTrackPad(leftHandDevice, rightHandDevice);
|
OnMenuButton(leftHandDevice, rightHandDevice);
|
OnGripButton(leftHandDevice, rightHandDevice);
|
|
|
|
}
|
|
|
|
private void GetDevice()
|
{
|
|
|
|
leftHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.LeftHand);
|
|
|
rightHandDevice = InputDevices.GetDeviceAtXRNode(XRNode.RightHand);
|
|
}
|
|
|
private void OnTrigger(InputDevice leftHandDevice, InputDevice rightHandDevice)
|
{
|
|
leftHandDevice.TryGetFeatureValue(CommonUsages.triggerButton, out leftTriggerPressed);
|
rightHandDevice.TryGetFeatureValue(CommonUsages.triggerButton, out rightTriggerPressed);
|
|
if ((rightTriggerPressed || leftTriggerPressed) && !triggerIsRunning)
|
{
|
|
triggerIsRunning = true;
|
TriggerSelect?.Invoke();
|
}
|
else if (!rightTriggerPressed && !leftTriggerPressed && triggerIsRunning)
|
{
|
|
triggerIsRunning = false;
|
TriggerSelectExit?.Invoke();
|
}
|
|
}
|
|
|
private void OnTrackPad(InputDevice leftHandDevice, InputDevice rightHandDevice)
|
{
|
|
|
leftHandDevice.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out leftTrackPadPressed);
|
rightHandDevice.TryGetFeatureValue(CommonUsages.primary2DAxisClick, out rightTrackPadPressed);
|
leftHandDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out leftTrackPos);
|
rightHandDevice.TryGetFeatureValue(CommonUsages.primary2DAxis, out rightTrackPos);
|
float angle = 0;
|
|
if (!primary2DAxisRightUpTouch)
|
{
|
angle = Mathf.Atan2(leftTrackPos.y, leftTrackPos.x) * Mathf.Rad2Deg;
|
//primary2DAxisLeftUpTouch = ActivateTeleportation(angle);
|
}
|
|
|
if (!primary2DAxisLeftUpTouch)
|
{
|
angle = Mathf.Atan2(rightTrackPos.y, rightTrackPos.x) * Mathf.Rad2Deg;
|
//primary2DAxisRightUpTouch = ActivateTeleportation(angle);
|
}
|
|
|
|
|
|
if (leftTrackPadPressed && !trackPadIsRunning)
|
{
|
trackPadIsRunning = true;
|
angle = Mathf.Atan2(leftTrackPos.y, leftTrackPos.x) * Mathf.Rad2Deg;
|
ActionTrackPad(angle);
|
|
}
|
else if (rightTrackPadPressed && !trackPadIsRunning)
|
{
|
trackPadIsRunning = true;
|
angle = Mathf.Atan2(rightTrackPos.y, rightTrackPos.x) * Mathf.Rad2Deg;
|
ActionTrackPad(angle);
|
|
}
|
else if (!rightTrackPadPressed && !leftTrackPadPressed && trackPadIsRunning)
|
{
|
trackPadIsRunning = false;
|
|
if (primary2DAxisUpSelect)
|
{
|
primary2DAxisUpSelect = false;
|
Primary2DAxisUpSelectExit?.Invoke();
|
}
|
else if (primary2DAxisRightSelect)
|
{
|
primary2DAxisRightSelect = false;
|
Primary2DAxisRightSelectExit?.Invoke();
|
}
|
else if (primary2DAxisLeftSelect)
|
{
|
primary2DAxisLeftSelect = false;
|
Primary2DAxisLeftSelectExit?.Invoke();
|
}
|
else if (primary2DAxisDownSelect)
|
{
|
primary2DAxisDownSelect = false;
|
Primary2DAxisDownSelectExit?.Invoke();
|
}
|
}
|
|
|
}
|
|
//private bool ActivateTeleportation(float angle)
|
//{
|
// if ((angle < 135 && angle >= 45)) // top
|
// {
|
// if (!trackPadIsTouch)
|
// {
|
// trackPadIsTouch = true;
|
// AnchorManager.Inst.SetActiveVisibleAnchor(trackPadIsTouch);
|
|
// }
|
|
// }
|
// else if (trackPadIsTouch)
|
// {
|
// trackPadIsTouch = false;
|
// AnchorManager.Inst.SetActiveVisibleAnchor(trackPadIsTouch);
|
// SafeArea.Inst.ShowWarningAlert();
|
|
// }
|
// return trackPadIsTouch;
|
//}
|
|
|
private void ActionTrackPad(float angle)
|
{
|
if (angle < 135 && angle >= 45) // top
|
{
|
primary2DAxisUpSelect = true;
|
Primary2DAxisUpSelect?.Invoke();
|
}
|
else if (angle < 45 && angle >= -45) // right
|
{
|
primary2DAxisRightSelect = true;
|
Primary2DAxisRightSelect?.Invoke();
|
}
|
else if ((angle < -135 && angle >= -180) || (angle <= 180 && angle >= 135))// left
|
{
|
primary2DAxisLeftSelect = true;
|
Primary2DAxisLeftSelect?.Invoke();
|
}
|
else
|
{
|
primary2DAxisDownSelect = true;
|
Primary2DAxisDownSelect?.Invoke();
|
}
|
|
}
|
|
|
|
private void OnGripButton(InputDevice leftHandDevice, InputDevice rightHandDevice)
|
{
|
leftHandDevice.TryGetFeatureValue(CommonUsages.gripButton, out leftGripPressed);
|
rightHandDevice.TryGetFeatureValue(CommonUsages.gripButton, out rightGripPressed);
|
|
if (leftGripPressed)
|
{
|
gripIsRunning = true;
|
|
|
|
|
}
|
else if (rightGripPressed)
|
{
|
gripIsRunning = true;
|
|
}
|
else if (!leftGripPressed && !rightGripPressed && gripIsRunning)
|
{
|
gripIsRunning = false;
|
|
}
|
|
}
|
|
public void ActionGripButton(HoverEnterEventArgs args)
|
{
|
|
|
}
|
|
|
private void OnMenuButton(InputDevice leftHandDevice, InputDevice rightHandDevice)
|
{
|
leftHandDevice.TryGetFeatureValue(CommonUsages.menuButton, out leftMenuPressed);
|
rightHandDevice.TryGetFeatureValue(CommonUsages.menuButton, out rightMenuPressed);
|
|
if ((leftMenuPressed || rightMenuPressed) && !menuIsRunning)
|
{
|
menuIsRunning = true;
|
|
|
Menu.SetActive(!Menu.activeSelf);
|
|
}
|
else if (!leftMenuPressed && !rightMenuPressed && menuIsRunning)
|
{
|
menuIsRunning = false;
|
}
|
|
}
|
|
|
|
|
|
|
|
private int GetSubMeshIndex(Mesh mesh, int triangleIndex)
|
{
|
if (mesh.isReadable == false)
|
{
|
Debug.LogError("You need to mark model's mesh as Read/Write Enabled in Import Settings.", mesh);
|
return 0;
|
}
|
|
int triangleCounter = 0;
|
for (int subMeshIndex = 0; subMeshIndex < mesh.subMeshCount; subMeshIndex++)
|
{
|
var indexCount = mesh.GetSubMesh(subMeshIndex).indexCount;
|
triangleCounter += indexCount / 3;
|
if (triangleIndex < triangleCounter)
|
{
|
return subMeshIndex;
|
}
|
}
|
|
Debug.LogError(
|
$"Failed to find triangle with index {triangleIndex} in mesh '{mesh.name}'. Total triangle count: {triangleCounter}",
|
mesh);
|
return 0;
|
}
|
//private void HideLineVisual(XRInteractorLineVisual lineVisual, bool active)
|
//{
|
|
|
// lineVisual.enabled = active;
|
//}
|
//private void OnTeleportActivate(InputAction.CallbackContext context)
|
|
|
//{
|
|
// Debug.Log("����");
|
// rayInteractor.enabled = true;
|
// _isActive = true;
|
//}
|
|
//private void OnTeleportCancel(InputAction.CallbackContext context)
|
//{
|
// rayInteractor.enabled = false;
|
// _isActive = false;
|
//}
|
}
|