using UnityEngine; using UnityEngine.XR.Interaction.Toolkit; using UnityEngine.XR; using UnityEngine.Events; public class VRInputManager : Singleton { /// /// 왼손, 오른손 컨트롤러 변수 /// private InputDevice rightHandDevice; private InputDevice leftHandDevice; /// /// 왼손, 오른손 물체 상호작용 관련 변수 /// public XRRayInteractor leftRay; public XRRayInteractor rightRay; /// /// 메뉴 ui 오브젝트 /// public GameObject Menu; //[SerializeField] private XRRayInteractor rayInteractor; //[SerializeField] private TeleportationProvider provider; //private InputAction _thumbstick; //private bool _isActive; //List inputDevices = new List(); 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; /// /// 각 버튼별 동작 시 이벤트 모음 /// 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; //} }