使用HTC vive基於unity做虛擬現實,需要用到steamVR插件,最近查找了很多資料,稍微做一下總結。
做虛擬現實無非是頭顯在場景中的camera功能以及手柄的操作功能。
(一)camera以及controller
第一種方法:此方法為最簡單最直接的方法,直接把插件中的prefab拖出來用即可。
此方法手柄和頭顯均沒有問題
第二種方法:把插件中的腳本SteamVR_Camera掛到任一camera上,然后點擊expand即可。而對於控制器手柄,則先建立一個游戲物體,添加腳本SteamVR_ControllerManager,然后在此游戲物體下建立兩個子游戲物體,然后添加腳本SteamVR_TrackedObject,Index設置為None,並添加SteamVR_ControllerManager腳本中的左右手柄;最后再在兩個子游戲物體上各添加一個游戲物體,添加腳本SteamVR_RenderModel用於渲染手柄的模型,並且跟蹤手柄的位置。至此就可以完成設置,進行工程了。
(二)controller各個按鈕功能
在SteamVR_Controller腳本中有各個按鍵按下的相關方法,可以自己實驗一下或者網上找相關資料看看相關,在此轉載http://www.cnblogs.com/czaoth/p/5610883.html#3648603,還是很全面的(當然了如有不妥請轉告,並會進行相應修改)。
using UnityEngine; using System.Collections; //檢測手柄功能的腳本 這個腳本掛到手柄上(controler(right)和controler(left))上 public class ButtonTouchAction : MonoBehaviour { //手柄 SteamVR_TrackedObject trackdeObjec; void Awake() { //獲取手柄上的這個組件 trackdeObjec = GetComponent<SteamVR_TrackedObject>(); } // Use this for initialization void Start () { } void FixedUpdate() { //獲取手柄輸入 var device = SteamVR_Controller.Input((int)trackdeObjec.index); //以下是api中復制出來的按鍵列表 /* public class ButtonMask { public const ulong System = (1ul << (int)EVRButtonId.k_EButton_System); // reserved public const ulong ApplicationMenu = (1ul << (int)EVRButtonId.k_EButton_ApplicationMenu); public const ulong Grip = (1ul << (int)EVRButtonId.k_EButton_Grip); public const ulong Axis0 = (1ul << (int)EVRButtonId.k_EButton_Axis0); public const ulong Axis1 = (1ul << (int)EVRButtonId.k_EButton_Axis1); public const ulong Axis2 = (1ul << (int)EVRButtonId.k_EButton_Axis2); public const ulong Axis3 = (1ul << (int)EVRButtonId.k_EButton_Axis3); public const ulong Axis4 = (1ul << (int)EVRButtonId.k_EButton_Axis4); public const ulong Touchpad = (1ul << (int)EVRButtonId.k_EButton_SteamVR_Touchpad); public const ulong Trigger = (1ul << (int)EVRButtonId.k_EButton_SteamVR_Trigger); } */ //同樣是三種按鍵方式,以后不做贅述 if (device.GetTouch(SteamVR_Controller.ButtonMask.Trigger)) { Debug.Log("按了 “trigger” “扳機鍵”"); //右手震動 //拉弓類似操作應該就是按住trigger(扳機)gettouch時持續調用震動方法模擬弓弦綳緊的感覺。 var deviceIndex2 = SteamVR_Controller.GetDeviceIndex(SteamVR_Controller.DeviceRelation.Rightmost); SteamVR_Controller.Input(deviceIndex2).TriggerHapticPulse(500); } if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Trigger)) { Debug.Log("按下了 “trigger” “扳機鍵”"); } if (device.GetTouchUp(SteamVR_Controller.ButtonMask.Trigger)) { Debug.Log("松開了 “trigger” “扳機鍵”"); //左手震動 var deviceIndex = SteamVR_Controller.GetDeviceIndex(SteamVR_Controller.DeviceRelation.Leftmost); SteamVR_Controller.Input(deviceIndex).TriggerHapticPulse(3000); //右手震動 var deviceIndex1 = SteamVR_Controller.GetDeviceIndex(SteamVR_Controller.DeviceRelation.Rightmost); SteamVR_Controller.Input(deviceIndex1).TriggerHapticPulse(3000); } //這三種也能檢測到 后面不做贅述 if(device.GetPressDown(SteamVR_Controller.ButtonMask.Trigger)) { Debug.Log("用press按下了 “trigger” “扳機鍵”"); } if (device.GetPress(SteamVR_Controller.ButtonMask.Trigger)) { Debug.Log("用press按了 “trigger” “扳機鍵”"); } if (device.GetPressUp(SteamVR_Controller.ButtonMask.Trigger)) { Debug.Log("用press松開了 “trigger” “扳機鍵”"); } //system鍵 圓盤下面那個鍵 // reserved 為Steam系統保留,用來調出Steam系統菜單 因此貌似自己加的功能沒啥用 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.System)) { Debug.Log("按下了 “system” “系統按鈕/Steam”"); } if (device.GetPressDown(SteamVR_Controller.ButtonMask.System)) { Debug.Log("用press按下了 “System” “系統按鈕/Steam”"); } //ApplicationMenu鍵 帶菜單標志的那個按鍵(在方向圓盤上面) if (device.GetTouchDown(SteamVR_Controller.ButtonMask.ApplicationMenu)) { Debug.Log("按下了 “ApplicationMenu” “菜單鍵”"); } if (device.GetPressDown(SteamVR_Controller.ButtonMask.ApplicationMenu)) { Debug.Log("用press按下了 “ApplicationMenu” “菜單鍵”"); } //Grip鍵 兩側的鍵 (vive雇佣兵游戲中的換彈鍵),每個手柄左右各一功能相同,同一手柄兩個鍵是一個鍵。 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Grip)) { Debug.Log("按下了 “Grip” “ ”"); } if (device.GetPressDown(SteamVR_Controller.ButtonMask.Grip)) { Debug.Log("用press按下了 “Grip” “ ”"); } //Axis0鍵 與圓盤有交互 與圓盤有關 //觸摸觸發 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Axis0)) { Debug.Log("按下了 “Axis0” “方向 ”"); } //按動觸發 if (device.GetPressDown(SteamVR_Controller.ButtonMask.Axis0)) { Debug.Log("用press按下了 “Axis0” “方向 ”"); } //Axis1鍵 目前未發現按鍵位置 //觸摸觸發 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Axis1)) { Debug.Log("按下了 “Axis1” “ ”"); } //按動觸發 if (device.GetPressDown(SteamVR_Controller.ButtonMask.Axis1)) { Debug.Log("用press按下了 “Axis1” “ ”"); } //Axis2鍵 目前未發現按鍵位置 //觸摸觸發 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Axis2)) { Debug.Log("按下了 “Axis2” “ ”"); } //按動觸發 if (device.GetPressDown(SteamVR_Controller.ButtonMask.Axis2)) { Debug.Log("用press按下了 “Axis2” “ ”"); } //Axis3鍵 未目前未發現按鍵位置 //觸摸觸發 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Axis3)) { Debug.Log("按下了 “Axis3” “ ”"); } //按動觸發 if (device.GetPressDown(SteamVR_Controller.ButtonMask.Axis3)) { Debug.Log("用press按下了 “Axis3” “ ”"); } //Axis4鍵 目前未發現按鍵位置 //觸摸觸發 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Axis4)) { Debug.Log("按下了 “Axis4” “ ”"); } //按動觸發 if (device.GetPressDown(SteamVR_Controller.ButtonMask.Axis4)) { Debug.Log("用press按下了 “Axis4” “ ”"); } //ATouchpad鍵 圓盤交互 //觸摸觸發 if (device.GetTouchDown(SteamVR_Controller.ButtonMask.Touchpad)) { Debug.Log("按下了 “Touchpad” “ ”"); //方法返回一個坐標 接觸圓盤位置 Vector2 cc = device.GetAxis(); Debug.Log(cc); // 例子:圓盤分成上下左右 float jiaodu = VectorAngle(new Vector2(1, 0), cc); Debug.Log(jiaodu); //下 if (jiaodu > 45 && jiaodu < 135) { Debug.Log("下"); } //上 if (jiaodu < -45 && jiaodu > -135) { Debug.Log("上"); } //左 if ((jiaodu < 180 && jiaodu > 135) || (jiaodu < -135 && jiaodu > -180)) { Debug.Log("左"); } //右 if ((jiaodu > 0 && jiaodu < 45) || (jiaodu > -45 && jiaodu < 0)) { Debug.Log("右"); } } //按動觸發 if (device.GetPressDown(SteamVR_Controller.ButtonMask.Touchpad)) { Debug.Log("用press按下了 “Touchpad” “ ”"); } } //方向圓盤最好配合這個使用 圓盤的.GetAxis()會檢測返回一個二位向量,可用角度划分圓盤按鍵數量 //這個函數輸入兩個二維向量會返回一個夾角 180 到 -180 float VectorAngle(Vector2 from, Vector2 to) { float angle; Vector3 cross = Vector3.Cross(from, to); angle = Vector2.Angle(from, to); return cross.z > 0 ? -angle : angle;
}