Unity3d 在使用Unity的SteamVR中,如何在抓取结束后将游戏对象的位置设置为初始位置?
对虚拟现实来说很陌生。我通过抓取从初始位置抓取游戏对象。当我抓取头盔并触摸我的身体碰撞器时,它会隐藏头盔。因此接下来我可能会拿起眼镜并将其应用到我的身体上(隐藏游戏对象)下一步,当我放置不正确的头盔时,第一个头盔应回到其初始位置,并应在场景中看到。类似地,场景中有许多游戏对象Unity3d 在使用Unity的SteamVR中,如何在抓取结束后将游戏对象的位置设置为初始位置?,unity3d,virtual-reality,steamvr,Unity3d,Virtual Reality,Steamvr,对虚拟现实来说很陌生。我通过抓取从初始位置抓取游戏对象。当我抓取头盔并触摸我的身体碰撞器时,它会隐藏头盔。因此接下来我可能会拿起眼镜并将其应用到我的身体上(隐藏游戏对象)下一步,当我放置不正确的头盔时,第一个头盔应回到其初始位置,并应在场景中看到。类似地,场景中有许多游戏对象 private void OnTriggerEnter(Collider other) { if (other.gameObject.tag == "Helmet")
private void OnTriggerEnter(Collider other)
{
if (other.gameObject.tag == "Helmet")
{
HideGameObject();
}
if (other.gameObject.tag == "Glasses")
{
HideGameObject();
}
if (other.gameObject.tag == "EarMuff")
{
HideGameObject();
}
if (other.gameObject.tag == "IncorrectHelmet")
{
HideGameObject();
}
if (other.gameObject.tag == "IncorrectGlasses")
{
HideGameObject();
}
if (other.gameObject.tag == "IncorrectEarMuff")
{
HideGameObject();
sendPickValues.Invoke(2, 0);
}
}
//另一个设置游戏对象位置的脚本
public class BackToPosition : MonoBehaviour
{
private Vector3 initialPosition;
private Quaternion initialRotation;
GameObject prevObject;
GameObject currObject;
// Start is called before the first frame update
void Start()
{
initialPosition = transform.position;
initialRotation = transform.rotation;
}
// Update is called once per frame
void Update()
{
}
public void BackToInitialPosition()
{
Debug.Log("Entered");
transform.position = initialPosition;
transform.rotation = initialRotation;
}
}
我没有试图将之前抓取的对象设置为初始位置。我可能会先选择错误的头盔,然后选择许多其他匹配的游戏对象,然后再更改为正确的头盔。此时,第一个头盔应设置为初始位置。这是我在SteamVR中用于抓取和释放船舵手柄的脚本,但应该是正确的您也可以使用:
[RequireComponent(typeof(Interactable))]
public class HandAttacher : MonoBehaviour
{
public UnityEvent OnGrab;
public UnityEvent OnRelease;
public UnityEvent OnHandEnter;
public UnityEvent OnHandLeave;
private Interactable interactable;
void Awake()
{
interactable = GetComponent<Interactable>();
}
/// this magic method is called by hand while hovering
protected virtual void HandHoverUpdate(Hand hand)
{
GrabTypes startingGrabType = hand.GetGrabStarting();
if (interactable.attachedToHand == null && startingGrabType != GrabTypes.None)
{
hand.AttachObject(gameObject, startingGrabType, Hand.AttachmentFlags.DetachFromOtherHand | Hand.AttachmentFlags.ParentToHand);
OnGrab?.Invoke();
}
}
protected virtual void OnHandHoverBegin(Hand hand)
{
OnHandEnter?.Invoke();
}
protected virtual void OnHandHoverEnd(Hand hand)
{
OnHandLeave?.Invoke();
}
protected virtual void HandAttachedUpdate(Hand hand)
{
if (hand.IsGrabEnding(gameObject))
{
hand.DetachObject(gameObject);
OnRelease?.Invoke();
}
}
}
[RequireComponent(typeof(可交互))]
公共类手持人员:单行为
{
昂格拉布公共单位;
公共单位事件发布;
公共单位事件处理中心;
公共单位事假;
私有可交互;
无效唤醒()
{
可交互=GetComponent();
}
///这个神奇的方法是在悬停时手动调用的
受保护的虚拟void handhowerupdate(手动)
{
GrabTypes startingGrabType=hand.GetGrabStarting();
if(interactiable.attachedToHand==null&&startingGrabType!=GrabTypes.None)
{
hand.AttachObject(游戏对象,startingGrabType,hand.AttachmentFlags.DetachFromOtherHand | hand.AttachmentFlags.ParentToHand);
OnGrab?.Invoke();
}
}
受保护的虚拟空间OnHandHoverBegin(手动)
{
OnHandEnter?.Invoke();
}
HandHoverEnd上受保护的虚拟空间(手动)
{
OnHandLeave?.Invoke();
}
受保护的虚拟无效HandAttachedUpdate(手动)
{
if(手动抓取(游戏对象))
{
拆离对象(游戏对象);
OnRelease?.Invoke();
}
}
}
基本上,它创建了Unity事件,您可以在编辑器的Inspector窗口或代码中添加侦听器
因此,在您的用例中,我会在发布时添加一个监听器,并将游戏对象的位置和旋转重置为之前的任何位置。如何获得游戏对象的初始位置。假设我有大约30个游戏对象,如何获得初始位置。我需要将此scriprt添加到所有游戏对象中吗?使用我的脚本中提到的“private Vector3 oldPosition”概念来保存位置,并在发布时使用此位置将Game Object恢复到初始位置。是的,您可以将此脚本添加到任何您希望能够连接到手上的内容中。在抓取时,记住变换的位置和旋转。发布时,将其恢复为这些值。如果您不想使用事件和侦听器,只需从上述类中编辑这些事件和侦听器,并在代码本身中恢复旋转和位置。