1. 程式人生 > >htc vive 中SteamVR Plugins入門之抓取物體、投擲

htc vive 中SteamVR Plugins入門之抓取物體、投擲

1、建立一個專案,刪除掉maincamera,匯入SteamVR的包,將teamVR拖進Hierarchy中,建立一個Planne和Sphere,將CameraRig拖動到Hierarchy檢視中,SteamVR不用拖動,會自動生成


2、調整小球的大小和位置,給小球新增一個Rigidbody,然後設定mass和drag


3、點選Model,新增一個Collider



3、Edit-->Project Settings-->Time


4、File --> Project Settings --> Physics


5、抓取並投擲的指令碼,將該指令碼分別掛載到左右手柄的controller上就可以執行

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[RequireComponent(typeof(SteamVR_TrackedObject))]

public class PickUp : MonoBehaviour {

    //追蹤的手柄
    SteamVR_TrackedObject trackedObj;
    //獲取輸入事件
    SteamVR_Controller.Device device;
    public Transform sphere;

    // Use this for initialization
    void Start () {
        trackedObj = GetComponent<SteamVR_TrackedObject>();
        Debug.Log("Start....................................."+trackedObj.name);
    }
	
	// Update is called once per frame
	void Update () {
        //獲取扳機鍵型別
        device = SteamVR_Controller.Input((int)trackedObj.index);
      
     }

 

    private void OnTriggerStay(Collider collider)
    {
        Debug.Log("OnTriggerStay.....................................");

        //抓取物體
        //觸控中
        if (device.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
        {
            // 不受重力影響
            collider.attachedRigidbody.isKinematic = true;
            //將物體設定到父級上
            collider.gameObject.transform.SetParent(gameObject.transform);
            Debug.Log("GetTouch.....................................");
        }


        //鬆開物體
        if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger))
        {
            Debug.Log("GetTouchUp.....................................");
            // 受重力影響
            collider.attachedRigidbody.isKinematic = false;
            //將父級置為空
            collider.gameObject.transform.SetParent(null);
            //投擲物體
            tossObject(collider.attachedRigidbody);
        }
    }

    //物體投擲
    void tossObject(Rigidbody rigidbody)
    {
        //如果是起始位置,則設定為起始位置,否則設定為父類
        Transform origin = trackedObj.origin ? trackedObj.origin : trackedObj.transform.parent;

        //如果起始位置部位空
        if(origin != null)
        {
            //將區域性座標轉換成世界座標
            rigidbody.velocity = origin.TransformVector((device.velocity));
            rigidbody.angularVelocity = origin.TransformVector((device.angularVelocity));
        }
        else
        {
            //設定速度
            rigidbody.velocity = device.velocity;
            //設定角速度
            rigidbody.angularVelocity = device.angularVelocity;
        }
    }


    //重置小球
    private void Reset()
    {
        //扣動扳機鍵
        if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Touchpad))
        {
            //重置位置
            sphere.transform.position = Vector3.zero;
            //重置速度
            sphere.GetComponent<Rigidbody>().velocity = Vector3.zero;
            //重置角速度
            sphere.GetComponent<Rigidbody>().angularVelocity = Vector3.zero;
        }
    }

}


5、扣動手柄的扳機的時候抓住小球



6、鬆開扳機時鬆開物體



7、當鬆開扳機的同時投擲物體


丟擲去之前小球的位置:


丟擲去之後小球的位置


參考資料:http://www.taikr.com/course/432/task/8518/show#

一、視野中找不到手柄


原因:1、手柄被隱藏掉了,沒有啟用

2、在unity5.6以上的版本需要新增Camera(eye)中新增兩個指令碼Steam VR_Update Poses和Steam VR_Camera

解決辦法:選中手柄,勾選左右手柄Controller和Model前面的複選框



分別在搜尋框中搜索“SteamVR_UpdatePoses”和“SteamVR_Camera”指令碼,並新增給Camera(eye),再次執行手柄就可以被渲染上了


二、其中一個手柄一直接觸不到小球


原因:Steam VR_Tracked Object中的Origin沒有置為none

解決辦法:

點選Controller,在Inspector面板找到Origin


點選右側的小圓圈,在彈出的視窗中選擇“None”



再次執行就可以看到手柄可以正常使用了


三、手柄接觸小球后,OnTriggerStay函式沒有被呼叫

原因:collider新增的位置有誤。該方法被呼叫的前提:

  1. 確保兩個物體都有碰撞器,且有一個勾選了觸發器

  2. 確保至少有一個物體有剛體


解決方法:

原來指令碼掛載的位置在model上,位置不對,正確設定小球和手柄後,建立的抓取物體的指令碼掛載到Controller上就可以了:


正確的做法是:

小球新增一個Collider,但是isTrigger沒有勾選,並且新增一個rigidbody


左右手柄的controller分別新增一個collider,並且勾選中trigger



model不新增collider和rigidbody元件