VR開發(fā)--HTC Vive基礎(chǔ)(2):瞬移功能實現(xiàn)

1采章、瞬移

因為HTC Vive活動范圍有限制(3m * 5m)运嗜,所以我們在實際的使用中,為了更好的瀏覽場景悯舟,查看場景担租,會使用這種移動的方式,達(dá)到游戲中的視野移動抵怎。
一般來說就是手柄選取一個位置翩活,通過扳機(jī)鍵確認(rèn)移動。
移動的方式有兩種:一種是水平移動即X便贵,Z軸移動;另一種就是垂直移動,即Y軸移動菠镇。

2、如何實現(xiàn)位置選瘸辛А利耍?

只要能得到目標(biāo)位置點(diǎn),我們就可以移動盔粹。那這種功能如何做隘梨?
使用射線檢測!
HTC Vive中有類似的腳本實現(xiàn)舷嗡,所以我們只需要修改相關(guān)的腳本就可以辦到轴猎,但是還是需要一定的編程功底。

腳本實現(xiàn):
將下面腳本復(fù)制就可进萄,

Paste_Image.png

修改類名捻脖,添加腳本

using UnityEngine;
using System.Collections;

public class CatchPointer : MonoBehaviour
{
    public bool active = true;
    public Color color;
    public float thickness = 0.002f;
    public GameObject holder;
    public GameObject pointer;
    bool isActive = false;
    public bool addRigidBody = false;
    public Transform reference;
    public event PointerEventHandler PointerIn;
    public event PointerEventHandler PointerOut;
    public Vector3 HitPoint;
    Transform previousContact = null;

    // Use this for initialization
    void Start ()
    {
        holder = new GameObject();
        holder.transform.parent = this.transform;
        holder.transform.localPosition = Vector3.zero;

        pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
        pointer.transform.parent = holder.transform;
        pointer.transform.localScale = new Vector3(thickness, thickness, 100f);
        pointer.transform.localPosition = new Vector3(0f, 0f, 50f);
        BoxCollider collider = pointer.GetComponent<BoxCollider>();
        if (addRigidBody)
        {
            if (collider)
            {
                collider.isTrigger = true;
            }
            Rigidbody rigidBody = pointer.AddComponent<Rigidbody>();
            rigidBody.isKinematic = true;
        }
        else
        {
            if(collider)
            {
                Object.Destroy(collider);
            }
        }
        Material newMaterial = new Material(Shader.Find("Unlit/Color"));
        newMaterial.SetColor("_Color", color);
        pointer.GetComponent<MeshRenderer>().material = newMaterial;
    }

    public virtual void OnPointerIn(PointerEventArgs e)
    {
        if (PointerIn != null)
            PointerIn(this, e);
    }

    public virtual void OnPointerOut(PointerEventArgs e)
    {
        if (PointerOut != null)
            PointerOut(this, e);
    }


    // Update is called once per frame
    void Update ()
    {
        if (!isActive)
        {
            isActive = true;
            this.transform.GetChild(0).gameObject.SetActive(true);
        }

        float dist = 100f;

        SteamVR_TrackedController controller = GetComponent<SteamVR_TrackedController>();

        Ray raycast = new Ray(transform.position, transform.forward);
        RaycastHit hit;
        bool bHit = Physics.Raycast(raycast, out hit);

        if(previousContact && previousContact != hit.transform)
        {
            PointerEventArgs args = new PointerEventArgs();
            if (controller != null)
            {
                args.controllerIndex = controller.controllerIndex;
            }
            args.distance = 0f;
            args.flags = 0;
            args.target = previousContact;
            OnPointerOut(args);
            previousContact = null;
        }
        if(bHit && previousContact != hit.transform)
        {
            PointerEventArgs argsIn = new PointerEventArgs();
            if (controller != null)
            {
                argsIn.controllerIndex = controller.controllerIndex;
            }
            argsIn.distance = hit.distance;
            argsIn.flags = 0;
            argsIn.target = hit.transform;
            OnPointerIn(argsIn);
            previousContact = hit.transform;
        }
        if(!bHit)
        {
            previousContact = null;
        }
        if (bHit && hit.distance < 100f)
        {
            dist = hit.distance;
        }
        if (bHit)
        {
            HitPoint = hit.point;
        }

        if (controller != null && controller.triggerPressed)
        {
            pointer.transform.localScale = new Vector3(thickness * 5f, thickness * 5f, dist);
        }
        else
        {
            pointer.transform.localScale = new Vector3(thickness, thickness, dist);
        }
        pointer.transform.localPosition = new Vector3(0f, 0f, dist/2f);
    }
}

3、添加腳本查看效果
Paste_Image.png
Paste_Image.png
4中鼠、如何傳送可婶?

編寫腳本進(jìn)行設(shè)置

using UnityEngine;
using System.Collections;

public class Teleport : MonoBehaviour {

    public GameObject LeftController;
    private CatchPointer Pointer;
    private SteamVR_TrackedController LeftSt;
    ClickedEventHandler ce;
    Transform currentTransform;
    PointerEventArgs arg;
    void Start () {
        Pointer = LeftController.GetComponent<CatchPointer>();
        LeftSt = LeftController.GetComponent<SteamVR_TrackedController>();
        Pointer.PointerIn += LeftPointIn;
        Pointer.PointerOut += LeftPointOut;
        LeftSt.TriggerClicked += TriggerClicked;

    }
    
    
    void Update () {
    
    }
    void LeftPointOut(object sender, PointerEventArgs e)
    {
        currentTransform = null;
    }
    void LeftPointIn(object sender, PointerEventArgs e)
    {   // 設(shè)置標(biāo)識
        currentTransform = e.target;
    }
    void TriggerClicked(object sender, ClickedEventArgs e)
    {
        if (currentTransform != null)
        {
            this.gameObject.transform.position = new Vector3(Pointer.HitPoint.x - LeftController.transform.localPosition.x, Pointer.HitPoint.y, Pointer.HitPoint.z - LeftController.transform.localPosition.z);
        }  
    }
}

5、如何實現(xiàn)拋物線功能

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末援雇,一起剝皮案震驚了整個濱河市矛渴,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌惫搏,老刑警劉巖具温,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異筐赔,居然都是意外死亡铣猩,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門川陆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剂习,“玉大人蛮位,你說我怎么就攤上這事×廴疲” “怎么了失仁?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長们何。 經(jīng)常有香客問我萄焦,道長,這世上最難降的妖魔是什么冤竹? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任拂封,我火速辦了婚禮,結(jié)果婚禮上鹦蠕,老公的妹妹穿的比我還像新娘冒签。我一直安慰自己,他們只是感情好钟病,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布萧恕。 她就那樣靜靜地躺著,像睡著了一般肠阱。 火紅的嫁衣襯著肌膚如雪票唆。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天屹徘,我揣著相機(jī)與錄音走趋,去河邊找鬼。 笑死噪伊,一個胖子當(dāng)著我的面吹牛簿煌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播酥宴,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼啦吧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了拙寡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤琳水,失蹤者是張志新(化名)和其女友劉穎肆糕,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體在孝,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡诚啃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了私沮。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片始赎。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出造垛,到底是詐尸還是另有隱情魔招,我是刑警寧澤,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布五辽,位于F島的核電站办斑,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏杆逗。R本人自食惡果不足惜乡翅,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望罪郊。 院中可真熱鬧蠕蚜,春花似錦、人聲如沸悔橄。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽橄维。三九已至尺铣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間争舞,已是汗流浹背凛忿。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留竞川,地道東北人店溢。 一個月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓,卻偏偏與公主長得像委乌,于是被迫代替她去往敵國和親床牧。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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