95 lines
3.0 KiB
C#
95 lines
3.0 KiB
C#
using UnityEngine;
|
|
|
|
public class VRInputPoseDetector : MonoBehaviour
|
|
{
|
|
[Header("参照")]
|
|
[SerializeField] private Transform headTransform;
|
|
[SerializeField] private Transform rightHandTransform;
|
|
[SerializeField] private Transform leftHandTransform;
|
|
|
|
[Header("判定パラメータ")]
|
|
[SerializeField] private float minForwardDistance = 0.15f;
|
|
[SerializeField] private float maxForwardDistance = 0.5f;
|
|
[SerializeField] private float minHeightOffset = -0.35f;
|
|
[SerializeField] private float maxHeightOffset = -0.1f;
|
|
|
|
[Header("タイマーパラメータ")]
|
|
[SerializeField] private float requiredPoseTime = 0.3f;
|
|
[SerializeField] private float poseExitDelay = 0.15f;
|
|
|
|
[Header("視覚フィードバック")]
|
|
[SerializeField] private Renderer guideRenderer;
|
|
[SerializeField] private Color defaultColor = new Color(0.5f, 0.5f, 0.5f, 0.05f);
|
|
[SerializeField] private Color chargingColor = new Color(1f, 0.8f, 0f, 0.2f);
|
|
[SerializeField] private Color successColor = new Color(0f, 0.6f, 1f, 0.4f);
|
|
|
|
private float poseTimer;
|
|
private float exitTimer;
|
|
|
|
public bool IsPosing { get; private set; }
|
|
|
|
private void Update()
|
|
{
|
|
if (headTransform == null || rightHandTransform == null || leftHandTransform == null) return;
|
|
|
|
Vector3 localRightHand = headTransform.InverseTransformPoint(rightHandTransform.position);
|
|
Vector3 localLeftHand = headTransform.InverseTransformPoint(leftHandTransform.position);
|
|
|
|
bool isBothHandsGuarding = CheckHandPosition(localRightHand) && CheckHandPosition(localLeftHand);
|
|
|
|
if (isBothHandsGuarding)
|
|
{
|
|
exitTimer = 0f;
|
|
|
|
if (!IsPosing)
|
|
{
|
|
poseTimer += Time.deltaTime;
|
|
if (poseTimer >= requiredPoseTime)
|
|
{
|
|
IsPosing = true;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
poseTimer = 0f;
|
|
|
|
if (IsPosing)
|
|
{
|
|
exitTimer += Time.deltaTime;
|
|
if (exitTimer >= poseExitDelay)
|
|
{
|
|
IsPosing = false;
|
|
exitTimer = 0f;
|
|
}
|
|
}
|
|
}
|
|
|
|
UpdateVisualFeedback(isBothHandsGuarding);
|
|
}
|
|
|
|
private bool CheckHandPosition(Vector3 localHandPos)
|
|
{
|
|
bool inForwardRange = localHandPos.z >= minForwardDistance && localHandPos.z <= maxForwardDistance;
|
|
bool inHeightRange = localHandPos.y >= minHeightOffset && localHandPos.y <= maxHeightOffset;
|
|
return inForwardRange && inHeightRange;
|
|
}
|
|
|
|
private void UpdateVisualFeedback(bool isBothHandsGuarding)
|
|
{
|
|
if (guideRenderer == null) return;
|
|
|
|
if (IsPosing)
|
|
{
|
|
guideRenderer.material.color = successColor;
|
|
}
|
|
else if (isBothHandsGuarding)
|
|
{
|
|
guideRenderer.material.color = chargingColor;
|
|
}
|
|
else
|
|
{
|
|
guideRenderer.material.color = defaultColor;
|
|
}
|
|
}
|
|
} |