四元数相对差

问题描述 投票:0回答:1

[我正在从事一个VR项目,我正在努力做一些不应该那么难的事情,但是我对数学很不满意:x

我想做的是,在世界上有“物理”按钮,我可以用手指按该按钮以使其按下/松开,该部分确实工作得很好,并且感觉很完美,但是:

当前,要“按下”按钮,我正在使用控制器的z delta位置,因此例如,由于需要y delta,所以无法从顶部按下按钮。

我正在尝试使按钮能够面向任何方向,并能够使用控制器的右轴来推动它们,但是却无法绕开它:x

我需要能够根据按钮的位置/旋转来按下按钮。

我不知道它是否真的可以理解(可能不是),也许我只是错过了一些非常明显的东西。

这是我的按钮代码,枚举部分可能没用,我只是在尝试大声笑

using System;
using UnityEngine;

public class JVRButton : MonoBehaviour, IJVRFingerInteract
{

    [SerializeField] private Vector3 pressedPosition;
    [SerializeField] private Vector3 defaultPosition;
    [SerializeField] private Vector3 unpressPosition;

    [SerializeField] private LinearDragNormal direction;

    public bool Pressed { get; private set; }
    public event Action<bool> OnStateChange;

    private bool _changedState;
    private Transform _transform;
    private Vector3 _tmp;
    private float _delay;

    private float _delta; 

    private void Awake()
    {
        _transform = transform;
        _transform.localPosition = Pressed ? pressedPosition : defaultPosition;
    }

    private void Update()
    {
        _delay += Time.deltaTime;
        if (_delay < 0.1f) return;

        // "Spring" effect
        _transform.localPosition = Vector3.MoveTowards(_transform.localPosition, Pressed ? pressedPosition : defaultPosition, Time.deltaTime / 2);
    }

    public void JVRFingerInteract(JVRFinger jvrFinger)
    {
        Vector3 test = Quaternion.FromToRotation(jvrFinger.transform.forward, _transform.forward).eulerAngles;

        Debug.Log(test);

        switch(direction)
        {
            case LinearDragNormal.XPositive:
                _delta = Mathf.Min(jvrFinger.JVRController.DeltaPositionLocal.z, 0);
                break;
            case LinearDragNormal.XNegative:
                _delta = Mathf.Max(jvrFinger.JVRController.DeltaPositionLocal.z, 0);
                break;
            case LinearDragNormal.YPositive:
                _delta = Mathf.Max(jvrFinger.JVRController.DeltaPositionLocal.y, 0);
                break;
            case LinearDragNormal.YNegative:
                _delta = Mathf.Min(jvrFinger.JVRController.DeltaPositionLocal.y, 0);
                break;
             case LinearDragNormal.ZPositive:
                _delta = Mathf.Min(jvrFinger.JVRController.DeltaPositionLocal.x, 0);
                break;
            case LinearDragNormal.ZNegative:
                _delta = Mathf.Max(jvrFinger.JVRController.DeltaPositionLocal.x, 0);
                break;
            default:
                throw new ArgumentOutOfRangeException();
        }

        MoveButton(Pressed ? unpressPosition : pressedPosition);
    }

    private void MoveButton(Vector3 position)
    {
        if (_changedState && _delay < 0.5f) return;
        _delay = 0;
        _changedState = false;            
        _tmp = _transform.localPosition;
        _tmp = Vector3.MoveTowards(_tmp, position, _delta);
        if (_tmp.x < position.x) _tmp.x = position.x;
        if (_tmp.y < position.y) _tmp.y = position.y;
        if (_tmp.z < position.z) _tmp.z = position.z;
        _transform.localPosition = _tmp;

        if (_transform.localPosition == pressedPosition)
        {
            Pressed = true;
            _changedState = true;
            OnStateChange?.Invoke(Pressed);
        }
        else if (_transform.localPosition == unpressPosition)
        {
            Pressed = false;
            _changedState = true;
            OnStateChange?.Invoke(Pressed);
        }
    }    
}

public enum LinearDragNormal
{
    XPositive,
    XNegative,
    YPositive,
    YNegative,
    ZPositive,
    ZNegative
}

[JVRFingerInteract被称为我的手指触摸按钮的每一帧,我只是在手指上做一个重叠球以获取可交互的对象。

unity3d quaternions
1个回答
0
投票

好吧,我通过尝试找到了解决方案,我不知道它为什么以及为什么起作用,但是确实可以...

_delta = (_forward.x * jvrPos.z + _forward.y * -jvrPos.y + _forward.z * -jvrPos.x);

_ forward是前进的按钮,而jvrPos是我的控制器/手指的本地增量

© www.soinside.com 2019 - 2024. All rights reserved.