如何检测Oculus Quest 2控制器0.5秒内向玩家旋转30度
Oculus Quest 2控制器旋转检测实现
核心触发条件
- 控制器绕自身轴向玩家方向旋转累计≥30度
- 完成该旋转的时间≥0.5秒
- 两个条件需同时满足,角度不足或用时短于0.5秒均不触发
代码实现
基于Unity Input System,结合你已定义的InputActionProperty变量,实现如下:
using UnityEngine; using UnityEngine.InputSystem; using System.Collections.Generic; public class ControllerRotationDetector : MonoBehaviour { // 你已定义的控制器旋转输入 [SerializeField] private InputActionProperty _rightRotationAction; [SerializeField] private InputActionProperty _leftRotationAction; // 检测参数配置 [SerializeField] private float requiredRotationAngle = 30f; [SerializeField] private float minRequiredTime = 0.5f; [SerializeField] private ControllerSide targetController = ControllerSide.Right; // 存储旋转历史(旋转值+时间戳) private Queue<(Quaternion rotation, float timestamp)> _rotationHistory = new Queue<(Quaternion, float)>(); private bool _isDetected = false; private enum ControllerSide { Left, Right } private void Update() { if (_isDetected) return; // 获取当前控制器旋转值 Quaternion currentRotation = targetController == ControllerSide.Right ? _rightRotationAction.action.ReadValue<Quaternion>() : _leftRotationAction.action.ReadValue<Quaternion>(); float currentTime = Time.time; _rotationHistory.Enqueue((currentRotation, currentTime)); // 清理超时历史并检测触发条件 while (_rotationHistory.Count > 0 && currentTime - _rotationHistory.Peek().timestamp > minRequiredTime) { var startRecord = _rotationHistory.Peek(); float angleDelta = CalculateRotationTowardsPlayer(startRecord.rotation, currentRotation); if (angleDelta >= requiredRotationAngle && currentTime - startRecord.timestamp >= minRequiredTime) { TriggerDetection(); break; } _rotationHistory.Dequeue(); } } // 计算控制器朝向玩家的有效旋转角度差 private float CalculateRotationTowardsPlayer(Quaternion startRot, Quaternion endRot) { Vector3 playerForward = Camera.main.transform.forward; Quaternion startToPlayer = Quaternion.FromToRotation(startRot * Vector3.forward, playerForward); Quaternion endToPlayer = Quaternion.FromToRotation(endRot * Vector3.forward, playerForward); float startYaw = startToPlayer.eulerAngles.y; float endYaw = endToPlayer.eulerAngles.y; float angleDelta = Mathf.DeltaAngle(startYaw, endYaw); // 仅统计朝向玩家的正向旋转 return angleDelta > 0 ? angleDelta : 0f; } // 触发检测后的逻辑 private void TriggerDetection() { _isDetected = true; Debug.Log("控制器旋转检测触发!"); // 此处添加自定义触发逻辑 // 如需重复检测,执行完逻辑后重置_isDetected为false即可 } // 重置检测状态(可选) public void ResetDetection() { _isDetected = false; _rotationHistory.Clear(); } }
关键说明
- 旋转有效性过滤:仅统计控制器朝向玩家的正向旋转,排除反向旋转的干扰
- 时间窗口管控:用队列存储历史旋转数据,实时清理超出0.5秒的记录,确保只检测符合时间要求的旋转过程
- 参数灵活调整:可通过Inspector面板修改旋转角度阈值、最小用时以及目标检测控制器
内容的提问来源于stack exchange,提问作者Alexander Kudryavy
相关产品推荐
相关产品推荐

