Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unity3d 在使用Unity的SteamVR中,如何在抓取结束后将游戏对象的位置设置为初始位置?_Unity3d_Virtual Reality_Steamvr - Fatal编程技术网

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恢复到初始位置。是的,您可以将此脚本添加到任何您希望能够连接到手上的内容中。在抓取时,记住变换的位置和旋转。发布时,将其恢复为这些值。如果您不想使用事件和侦听器,只需从上述类中编辑这些事件和侦听器,并在代码本身中恢复旋转和位置。