【GearVR】Gear VR 獲取用戶輸入

首先簡(jiǎn)單介紹下Gear VR頭盔上的功能按鍵:

Gear VR 第一代 的功能按鍵全部位于頭盔右側(cè),分別如下: 兩個(gè)音量增減鍵,用來(lái)調(diào)節(jié)手機(jī)的音量,功能和手機(jī)本身的音量鍵完全一樣一個(gè)返回鍵,類似android手機(jī)上的返回鍵,在VR游戲中可以用來(lái)實(shí)現(xiàn),返回主菜單,或者退出游戲之類的操作觸控區(qū)域,可以通過(guò)該區(qū)域識(shí)別玩家的點(diǎn)擊,按下,松開(kāi),雙擊,長(zhǎng)按,以及滑動(dòng)操作,這將是玩家在游戲內(nèi)的主要操作方式(還有一個(gè)就是頭部的轉(zhuǎn)動(dòng))。當(dāng)然從個(gè)人體驗(yàn)來(lái)講,因?yàn)樵搮^(qū)域位于頭部側(cè)方,不同于手機(jī)屏幕,不適合讓玩家通過(guò)滑動(dòng)來(lái)完成太復(fù)雜的操作,超過(guò)上下左右四方向以外的滑動(dòng)識(shí)別,體驗(yàn)都不是很好。

通過(guò)圖片和按鍵講解可以看到,gearVR 與暴風(fēng)魔鏡之流的設(shè)備的區(qū)別就是,它通過(guò)USB口連接手機(jī),然后玩家可以通過(guò)頭戴設(shè)備的輸入完成一些相對(duì)完善的操作。

Unity是如何映射這些功能按鍵的:用Unity創(chuàng)建一個(gè)空項(xiàng)目,GearVRTest_1_2,然后打開(kāi)InputManager:通過(guò)Edit-> Project Settings ->Input

點(diǎn)開(kāi)第一個(gè)Fire1:可以看到這個(gè)名稱對(duì)應(yīng)的按鍵是Left Ctrl(鍵盤(pán)上的左Ctrl鍵),以及mouse 0(鼠標(biāo)左鍵,同時(shí)也是觸屏手機(jī)的單點(diǎn)觸屏操作,也是GearVR touchpad的點(diǎn)擊操作)點(diǎn)開(kāi)第二個(gè)Fire1:可以看到對(duì)應(yīng)的是joystick button 0 (也就是手柄上第二排第一個(gè)按鍵)點(diǎn)開(kāi)唯一的一個(gè)Cancel:可以看到對(duì)應(yīng)的是escape(鍵盤(pán)左上角的esc鍵和安卓手機(jī)和GearVR的返回鍵),以及joystick button 1(手柄上的第二個(gè)按鍵)通過(guò)這些按鍵映射可以看到,我們可以通過(guò)合理的按鍵映射,可以使我們的VR游戲做到手機(jī),頭顯和藍(lán)牙手柄公用一套按鍵邏輯(VR頭顯bing)

通過(guò)代碼獲取玩家操作:我們要實(shí)現(xiàn)的是一個(gè)獲取玩家輸入的腳本,而不處理具體邏輯,行為邏輯代碼通過(guò)委托的方式從該腳本獲取玩家的操作




using UnityEngine;

using System.Collections;

using System;

namespace com.bt.gearVR

{

publicclassVRInput : MonoBehaviour

{

publicenumSwipeDirection

{

NONE,

UP,

DOWN,

LEFT,

RIGHT,

};

publicevent Action OnSwipe;//在touchPad上滑動(dòng)

publicevent Action OnClick;//點(diǎn)擊touchPad

publicevent Action OnDown;//按下

publicevent Action OnUp;//抬起

publicevent Action OnDoubleClick;//雙擊

publicevent Action OnCancel;//點(diǎn)擊touchPad的返回鍵

[SerializeField]privatefloatm_DoubleClickTime=0.3f;//有效雙擊的最大時(shí)間間隔

[SerializeField]privatefloatm_SwipeWidth=0.3f;//有效滑動(dòng)的最小位移

privateVector2 m_MouseDownPosition;//記錄手指按下的位置

privateVector2 m_MouseUpPosition;//記錄手指抬起的位置

privatefloatm_LastMouseUpTime;//上一次手指抬起的時(shí)間,用來(lái)檢測(cè)雙擊

privatefloatm_LastHorizontalValue;

privatefloatm_LastVerticalValue;

publicfloatDoubleClickTime { get {returnm_DoubleClickTime; } }

// Use this for initialization

voidStart()

{

}

// Update is called once per frame

privatevoidUpdate()

{

CheckInput();

}

privatevoidCheckInput()

{

SwipeDirection swipe = SwipeDirection.NONE;

if(Input.GetButtonDown("Fire1"))//手指觸碰到touchPad

{

m_MouseDownPosition =newVector2(Input.mousePosition.x, Input.mousePosition.y);

if(OnDown!=null)

{

OnDown();

}

}

if(Input.GetButtonUp("Fire1"))//手指離開(kāi)touchPad

{

m_MouseUpPosition =newVector2(Input.mousePosition.x, Input.mousePosition.y);

swipe = DetectSwipe();//

}

if(swipe==SwipeDirection.NONE)

{

swipe = DetectKeyboardEmulatedSwipe();

}

if(OnSwipe!=null)

{

OnSwipe(swipe);

}

if(Input.GetButtonUp("Fire1"))

{

if(OnUp!=null)

{

OnUp();

}

if(Time.time-m_LastMouseUpTime

/// 檢測(cè)滑動(dòng)方向

///

/// 滑動(dòng)方向,上下左右

privateSwipeDirection DetectSwipe()

{

Vector2 swipeData = (m_MouseUpPosition - m_MouseDownPosition).normalized;

bool swipeIsVertical = Mathf.Abs(swipeData.x) < m_SwipeWidth;

bool swipeIsHorizontal = Mathf.Abs(swipeData.y) < m_SwipeWidth;

if(swipeData.y>0f && swipeIsVertical)

{

returnSwipeDirection.UP;

}

if(swipeData.y<0&& swipeIsVertical)

{

returnSwipeDirection.DOWN;

}

if(swipeData.x>0&& swipeIsHorizontal)

{

returnSwipeDirection.RIGHT;

}

if(swipeData.x<0&& swipeIsHorizontal)

{

returnSwipeDirection.LEFT;

}

returnSwipeDirection.NONE;

}

//檢測(cè)鍵盤(pán)或者手柄模擬的晃動(dòng)方向

privateSwipeDirection DetectKeyboardEmulatedSwipe()

{

floathorizontal = Input.GetAxis("Horizontal");

floatvertical = Input.GetAxis("Vertical");

bool noHorizontalInputPreviously = Mathf.Abs(m_LastHorizontalValue)

bool noVerticalInputPreviously = Mathf.Abs(m_LastVerticalValue)

m_LastHorizontalValue = horizontal;

m_LastVerticalValue = vertical;

if(vertical > 0f && noVerticalInputPreviously)

returnSwipeDirection.UP;

if(vertical < 0f && noVerticalInputPreviously)

returnSwipeDirection.DOWN;

if(horizontal > 0f && noHorizontalInputPreviously)

returnSwipeDirection.RIGHT;

if(horizontal < 0f && noHorizontalInputPreviously)

returnSwipeDirection.LEFT;

returnSwipeDirection.NONE;

}

privatevoidOnDestroy()

{

OnSwipe =null;

OnClick =null;

OnDoubleClick =null;

OnDown =null;

OnUp =null;

}

}

}



然后是測(cè)試代碼,后面會(huì)上傳項(xiàng)目路徑,會(huì)有一個(gè)控制玩家移動(dòng)的腳本,這里不再貼出


using UnityEngine;

using System.Collections;

namespace com.bt.gearVR

{

publicclassVRInputTest : MonoBehaviour

{

[SerializeField]privateVRInput m_VRInput;

//該腳本激活時(shí),注冊(cè)對(duì)玩家操作的監(jiān)聽(tīng)

voidOnEnable()

{

m_VRInput.OnCancel += OnCalcel;

m_VRInput.OnClick += OnClick;

m_VRInput.OnDown += OnDown;

m_VRInput.OnUp += OnUp;

m_VRInput.OnDoubleClick += OnDoubleClick;

m_VRInput.OnSwipe += OnSwip;

}

voidOnSwip(VRInput.SwipeDirection swipeDirection)

{

if(swipeDirection!=VRInput.SwipeDirection.NONE)

{

Debug.Log("Unity+OnSwipe"+ swipeDirection);

}

}

//取消對(duì)玩家輸入的監(jiān)聽(tīng)

voidOnDisable()

{

m_VRInput.OnCancel -= OnCalcel;

m_VRInput.OnClick -= OnClick;

m_VRInput.OnDown -= OnDown;

m_VRInput.OnUp -= OnUp;

m_VRInput.OnDoubleClick -= OnDoubleClick;

m_VRInput.OnSwipe -= OnSwip;

}

voidOnCalcel()

{

Debug.Log("Unity+OnCancel");

}

voidOnClick()

{

Debug.Log("Unity+OnClick");

}

voidOnDown()

{

Debug.Log("Unity+OnDown");

}

voidOnUp()

{

Debug.Log("Unity+OnUp");

}

voidOnDoubleClick()

{

Debug.Log("Unity+OnDoubleClick");

}

// Use this for initialization

voidStart()

{

}

}

}



注1:GearVR第二代又新加了一個(gè)Home鍵,功能類似于手機(jī)上的Home鍵,游戲內(nèi)用不到這里不再列出

注2:玩家在游戲內(nèi)移動(dòng)時(shí),不可以直接移動(dòng)攝像機(jī)本身,因?yàn)镚earVR限制了攝像機(jī)的移動(dòng),但是可以把攝像機(jī)掛到一個(gè)父節(jié)點(diǎn)下,通過(guò)移動(dòng)父節(jié)點(diǎn)來(lái)移動(dòng)攝像機(jī)注3:本教程中的部分代碼和圖片來(lái)源于Unity官方的教程,VRSamples,感興趣的讀者可以去AssetsStore下載Demo下載地

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容