Unity XR Interaction Toolkit(四)VR按钮

制作一个可以用手柄按下的按钮

这个功能不用三中的Transformer,因为按钮不用跟着手柄移动,所以是一个静止的物体

(如果能帮到你,请点一个赞吧)

首先创建一个空物体,添加刚体,关闭刚体的重力Use Gravity打开Is Kinematic

创建一个子物体在这个空物体下,放置按钮的模型,并添加碰撞体

这个物体也可以跟射线交互,如果想只能近距离交互,就修改手柄和物体的交互层级

创建一个脚本ButtonInteractable,继承XRBaseInteractable,删掉所有函数

首先重写ProcessInteractable函数,由于父类会在Dynamic和OnBeforeRender两个模式下运行,逻辑需要二选一,ProcessInteractable会一直运行,相当于Update

然后需要判断在物体被Hovered时候,按钮跟随手柄移动,并且需要两个函数,设置按钮在物体上方的方向,设置和获取高度

还需要在手柄触摸物体时,获取接触点到按钮坐标之间的偏差值,手柄结束Hover的时候,恢复按钮的初始高度

最后上代码

using System.Collections;
using System.Collections.Generic;
using Unity.XR.CoreUtils;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;

public class ButtonInteractable : XRBaseInteractable
{
    [SerializeField] Transform buttonTransform;
    float initHeight;

    float offset;

    private void Start()
    {
        initHeight = GetButtonHeight(buttonTransform.position);
    }

    protected override void OnEnable()
    {
        base.OnEnable();
        hoverEntered.AddListener(StartPush);
        hoverExited.AddListener(StopPush);
    }

    protected override void OnDisable()
    {
        base.OnDisable();
        hoverEntered.RemoveListener(StartPush);
        hoverExited.RemoveListener(StopPush);
    }

    void StartPush(HoverEnterEventArgs args)
    {
        var interactor = args.interactorObject;
        var interactorAttachPose = interactor.GetAttachTransform(this).GetWorldPose();

        offset = GetButtonHeight(interactorAttachPose.position);
        offset -= GetButtonHeight(buttonTransform.position);
    }

    void StopPush(HoverExitEventArgs args)
    {
        SetButtonHeight(initHeight);
    }

    public override void ProcessInteractable(XRInteractionUpdateOrder.UpdatePhase updatePhase)
    {
        switch (updatePhase)
        {
            case XRInteractionUpdateOrder.UpdatePhase.Dynamic:
                UpdateTarget();
                break;
        }
    }

    private void UpdateTarget()
    {
        if (isHovered)
        {
            var interactor = interactorsHovering[0];
            var interactorAttachPose = interactor.GetAttachTransform(this).GetWorldPose();

            float y = GetButtonHeight(interactorAttachPose.position);
            SetButtonHeight(y - offset);
        }
    }

    private void SetButtonHeight(float y)
    {
        y = Mathf.Clamp(y, 0, initHeight);
        buttonTransform.position = transform.position + transform.up * y;
    }

    private float GetButtonHeight(Vector3 pos)
    {
        return Vector3.Dot(transform.up, pos - transform.position);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_36608844/article/details/133856306
今日推荐