基于SteamVR_Unity_Toolkit自定義射線觸發(fā)器簡單結(jié)構(gòu)

環(huán)境:HtcVive灭忠,Unity简卧,C#屠橄,商店的SteamVR_Unity_Toolkit插件

目前htc交互比較主流的還是那個(gè)實(shí)體射線交互,工具包自帶的三種:

GetComponent().DestinationMarkerEnter

GetComponent().DestinationMarkerExit

GetComponent().DestinationMarkerSet

工具包自帶的三種交互使用起來不太靈活闰挡,自己在VRTK_SimplePointer基礎(chǔ)上拓展了一點(diǎn)功能锐墙,這里提供一個(gè)簡單的例子:

廢話不多說直接上:

/// <summary>
/// 這是M,不多說
/// </summary>
public class Msg_PointTrigger
{
    public  const string PointEnterMsg = "EnterTrigger";
    public  const string PointStayDownMsg = "PointStayDownMsg";
    public  const string PointStayUpMsg = "PointStayUPMsg";
    public  const string PointExittMsg = "ExittMsg";
    /*
     * 這里只做了4種长酗,后期可以跟進(jìn)
     */
}

1溪北、這是Base模版,大概思路是夺脾,觸發(fā)后根據(jù)消息解析做出相應(yīng)處理之拨,還是比較靈活的。

public class SteamVR_PointTriggerBase : MonoBehaviour {
    //左右手柄輸入器
    public SteamVR_TrackedObject rightTracket;
    public SteamVR_TrackedObject leftTracket;
    //左右射線頭位置
    public Transform rightPoint;
    public Transform leftPoint;
    protected string msg;
    /// <summary>
    /// 有響應(yīng)
    /// </summary>
    /// <param name="msg"></param>
    public virtual void Trigger(string msg)
    {
        this.msg = msg;
        ExplainMSg();
    }
    private  void ExplainMSg()
    {
        switch (msg)
        {
            case Msg_PointTrigger.PointEnterMsg :
                OnPointEnter();
                break;
            case Msg_PointTrigger.PointStayDownMsg:
                OnPointStayDown();
                break;
            case Msg_PointTrigger.PointStayUpMsg:
                OnPointStayUp();
                break;
            case Msg_PointTrigger.PointExittMsg:
                OnExitState();
                break;
            default:
                break;
        }
    }
    /// <summary>
    /// 射線按下進(jìn)入
    /// </summary>
    protected virtual void OnPointEnter() { Debug.Log("OnPointEnter"); }
    /// <summary>
    /// 射線按下且在物體上
    /// </summary>
    protected virtual void OnPointStayDown() 
    {
        //以下時(shí)我目前根據(jù)項(xiàng)目加新增的咧叭,后期可以獨(dú)立出來
        EffectHighting.AddConstantHighting(gameObject);
        if (null!=rightTracket)
        {
            SteamVR_Controller.Device rightDevice = SteamVR_Controller.Input((int)rightTracket.index);
            if (rightDevice.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
            {
                Debug.Log("右手Triger按下");
               OnPointStayDownRightTriggerTouch();
            }
        }
        if (null!=leftTracket)
        {
            SteamVR_Controller.Device leftDevice = SteamVR_Controller.Input((int)leftTracket.index);
            if (leftDevice.GetTouch(SteamVR_Controller.ButtonMask.Trigger))
            {
                Debug.Log("左手Triger按下");

                OnPointStayDownLeftTriggerTouch();
            }
        }
    }
    //這倆是臨時(shí)加的為:當(dāng)進(jìn)入時(shí)左右手鉤住扳機(jī)
    protected virtual void OnPointStayDownRightTriggerTouch() { }
    protected virtual void OnPointStayDownLeftTriggerTouch() { } 
    //當(dāng)射線在物體上時(shí)彈起發(fā)射線按鈕
    protected virtual void OnPointStayUp() { Debug.Log("OnPointStayUp"); }
    //退出
    protected virtual void OnExitState() {EffectHighting.ResetRemoveHightingEffect();Debug.Log("OnExitState"); }

2蚀乔、使用的例子:

如我寫的一個(gè)控制燈的開關(guān)的功能,只需要利用其中一種就可以了:

public class SteamVR_PointTriggerLights : SteamVR_PointTriggerBase
{
    public bool isOn = false;
    //變色
    public void TrunColor(Color openColor, Color closeColor)
    {
        if (isOn)
        {
            gameObject.GetComponent<MeshRenderer>().material.color = openColor;
        }
        else
        {
            gameObject.GetComponent<MeshRenderer>().material.color = closeColor; ;
        }
    }
    //開關(guān)燈
    private void TurnLights(bool isOn)
    {
        PointLightControler.instance.TurnLights(isOn);
    }
    protected override void OnPointEnter()
    {
        base.OnPointEnter();
    }
    protected override void OnPointStayDown()
    {
        base.OnPointStayDown();
    }
    protected override void OnPointStayDownRightTriggerTouch()
    {
        base.OnPointStayDownRightTriggerTouch();
    }
    protected override void OnPointStayDownLeftTriggerTouch()
    {
        base.OnPointStayDownLeftTriggerTouch();
    }
    //只個(gè)只用到了一種回調(diào):當(dāng)射線進(jìn)入并在內(nèi)部彈起后響應(yīng)
    protected override void OnPointStayUp()
    {
        base.OnPointStayUp();

        isOn = !isOn;
        TrunColor(Color.green, Color.red);
        TurnLights(isOn);
        Debug.Log("OnPointStayUp");
    }
    protected override void OnExitState()
    {
        base.OnExitState();
    }
}

3菲茬、下面是改寫的VRTK_SimplePointer吉挣,臨時(shí)改的,還沒有優(yōu)化過婉弹,后期可以補(bǔ)上睬魂,思路就是利用射線檢測判斷一些情況的邏輯,主要是改了Update方法镀赌,附上參考一下

 protected override void Update()
        {
            base.Update();
            if (pointer.gameObject.activeSelf)
            {
                RaycastHit pointerCollidedWith;
                Ray pointerRaycast = new Ray(transform.position, transform.forward);
                var rayHit = Physics.Raycast(pointerRaycast, out pointerCollidedWith, pointerLength, ~layersToIgnore);
                var pointerBeamLength = GetPointerBeamLength(rayHit, pointerCollidedWith);
                SetPointerTransform(pointerBeamLength, pointerThickness);
                //增加射線觸發(fā)事件
                //是否檢測到物體
                if (null!=pointerCollidedWith.collider)
                {
                    selectObj = pointerCollidedWith.collider.gameObject;

                }
                else
                {
                    /*
                     * -------------NO1
                     * 按下射線移出物體
                     */
                    if (null!=selectObj)
                    {
                        if (null != selectObj.GetComponent<SteamVR_PointTriggerBase>())
                        {
                            selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointExittMsg);
                        }
                    }
                    selectObj = null;
                    canEnter = true;
                }      
                //當(dāng)檢檢測到物體時(shí)
                if (null != selectObj)
                {
                    //物體是VR交互物體
                    if (null != selectObj.GetComponent<SteamVR_PointTriggerBase>())
                    {
                        /*
                         * --------------NO2
                         * 射線按下Enter事件
                         */
                        if (canEnter)
                        {
                            canEnter = false;
                            if (transform.root.GetComponent<SteamVR_ControllerManager>().right.activeSelf)
                            {
                                selectObj.GetComponent<SteamVR_PointTriggerBase>().rightTracket = transform.root.GetComponent<SteamVR_ControllerManager>().right.GetComponent<SteamVR_TrackedObject>();
                                selectObj.GetComponent<SteamVR_PointTriggerBase>().rightPoint = pointerTip.transform;
                                //Debug.Log(pointerTip.transform.position);
                            }
                            if (transform.root.GetComponent<SteamVR_ControllerManager>().left.activeSelf)
                            {
                                selectObj.GetComponent<SteamVR_PointTriggerBase>().leftTracket = transform.root.GetComponent<SteamVR_ControllerManager>().left.GetComponent<SteamVR_TrackedObject>();
                                selectObj.GetComponent<SteamVR_PointTriggerBase>().leftPoint = pointerTip.transform;
                            }
                            selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointEnterMsg);
                        }
                        /*
                         * ------------NO3
                         * 射線按下Stay事件
                         */
                        selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointStayDownMsg);
                    }
                }
            }
            else
            {
                if (null != selectObj)
                {
                    if (null != selectObj.GetComponent<SteamVR_PointTriggerBase>())
                    {

                        /*
                         * --------------------------NO4
                         * 當(dāng)射線在檢測物體內(nèi)氯哮,彈按鈕回掉
                         */
                        selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointStayUpMsg);
                        selectObj.GetComponent<SteamVR_PointTriggerBase>().Trigger(Msg_PointTrigger.PointExittMsg);
                        selectObj = null;
                    }
                }
            }
        }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市佩脊,隨后出現(xiàn)的幾起案子蛙粘,更是在濱河造成了極大的恐慌,老刑警劉巖威彰,帶你破解...
    沈念sama閱讀 217,277評(píng)論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異穴肘,居然都是意外死亡歇盼,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評(píng)論 3 393
  • 文/潘曉璐 我一進(jìn)店門评抚,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豹缀,“玉大人,你說我怎么就攤上這事慨代⌒象希” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵侍匙,是天一觀的道長氮惯。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么妇汗? 我笑而不...
    開封第一講書人閱讀 58,356評(píng)論 1 293
  • 正文 為了忘掉前任帘不,我火速辦了婚禮,結(jié)果婚禮上杨箭,老公的妹妹穿的比我還像新娘寞焙。我一直安慰自己,他們只是感情好互婿,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評(píng)論 6 392
  • 文/花漫 我一把揭開白布捣郊。 她就那樣靜靜地躺著,像睡著了一般慈参。 火紅的嫁衣襯著肌膚如雪模她。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評(píng)論 1 301
  • 那天懂牧,我揣著相機(jī)與錄音侈净,去河邊找鬼。 笑死僧凤,一個(gè)胖子當(dāng)著我的面吹牛畜侦,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播躯保,決...
    沈念sama閱讀 40,135評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼旋膳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了途事?” 一聲冷哼從身側(cè)響起验懊,我...
    開封第一講書人閱讀 38,992評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎尸变,沒想到半個(gè)月后义图,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡召烂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評(píng)論 3 334
  • 正文 我和宋清朗相戀三年碱工,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片奏夫。...
    茶點(diǎn)故事閱讀 39,785評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡怕篷,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出酗昼,到底是詐尸還是另有隱情廊谓,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評(píng)論 5 345
  • 正文 年R本政府宣布麻削,位于F島的核電站蒸痹,受9級(jí)特大地震影響春弥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜电抚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評(píng)論 3 328
  • 文/蒙蒙 一惕稻、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蝙叛,春花似錦俺祠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肺然,卻和暖如春蔫缸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背际起。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評(píng)論 1 269
  • 我被黑心中介騙來泰國打工拾碌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人街望。 一個(gè)月前我還...
    沈念sama閱讀 47,891評(píng)論 2 370
  • 正文 我出身青樓校翔,卻偏偏與公主長得像,于是被迫代替她去往敵國和親灾前。 傳聞我的和親對(duì)象是個(gè)殘疾皇子防症,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • This article is a record of my journey to learn Game Deve...
    蔡子聰閱讀 3,781評(píng)論 0 9
  • 111. [動(dòng)畫系統(tǒng)]如何將其他類型的動(dòng)畫轉(zhuǎn)換成關(guān)鍵幀動(dòng)畫? 動(dòng)畫->點(diǎn)緩存->關(guān)鍵幀 112. [動(dòng)畫]Unit...
    胤醚貔貅閱讀 13,017評(píng)論 3 90
  • SteamVR各腳本的功能 SteamVR/Scripts/下腳本各功能的實(shí)現(xiàn) 1哎甲、SteamVR.cs 單例管理...
    _涼笙閱讀 12,916評(píng)論 12 11
  • 這個(gè)世界總是太匆忙 你說世界欠你一個(gè)老譚 你卻活不成安迪 故事很俗套蔫敲,不知道你們愛不愛 L小姐某外企白領(lǐng),28歲 ...
    漠上女子閱讀 403評(píng)論 2 2
  • 根據(jù)于文博老師《讓生命微微笑》課程編輯整理 你的今天就是你過去一切“信”的呈現(xiàn),如果你對(duì)你的現(xiàn)在很滿意础嫡,請繼續(xù)信你...
    軒銘雜談閱讀 165評(píng)論 0 0