制作一个可以用手柄按下的按钮
这个功能不用三中的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);
}
}