VR開發(fā)實(shí)戰(zhàn)之HTC Vive實(shí)現(xiàn)瞬移功能

一.什么是瞬移功能曲初?

瞬移就是使用手柄選取一個位置体谒,通過扳機(jī)鍵進(jìn)行瞬間移動杯聚。
因?yàn)镠TC Vive活動范圍有限制(3m * 5m)臼婆,所以我們在實(shí)際的使用中,為了更好的瀏覽場景幌绍,查看場景颁褂,會使用這種移動的方式,達(dá)到游戲中的視野移動傀广。
移動的方式有兩種:一種是水平移動即X颁独,Z軸移動;另一種就是垂直移動,即Y軸移動。
PS : 我們通過射線檢測的方法進(jìn)行開發(fā)伪冰,因?yàn)镠TC Vive有類似的腳本誓酒。所以我們只需更改腳本的某些部分就可實(shí)現(xiàn)瞬移功能。

二.案例詳解

1.下載Steam VR贮聂,導(dǎo)入資源
2.將腳本復(fù)制靠柑,修改類名(部分腳本)
using UnityEngine;
using System.Collections;

public class SteamVR_LaserPointer : 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;
    holder.transform.localRotation = Quaternion.identity;

    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);
    pointer.transform.localRotation = Quaternion.identity;
    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)
    {
        HitPoint = hit.point;
    }
    if (bHit && hit.distance < 100f)
    {
        dist = hit.distance;
    }

    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.添加腳本
4.添加傳送腳本
public class Test_TelePointer : MonoBehaviour {

//拿到手柄對象
public GameObject LeftController;
//修改后的射線檢查腳本
private Test_LaserPointer Pointer;
//右手柄的控制器
private SteamVR_TrackedController LeftSt;
//事件調(diào)用函數(shù)
ClickedEventHandler ce;
//當(dāng)前的目標(biāo)位置
Transform currentTransform;
    //碰撞事件
PointerEventArgs arg;

void Start () {
    Pointer = LeftController.GetComponent<Test_LaserPointer>();
    LeftSt = LeftController.GetComponent<SteamVR_TrackedController>();
    //利用Laserpoint里面的事件函數(shù)來檢測目標(biāo)位置
    Pointer.PointerIn += LeftPointIn;
    //利用Laserpoint里面的事件函數(shù)來檢測目標(biāo)位置
    Pointer.PointerOut += LeftPointOut;
    //利用手柄控制器來檢測我們的扳機(jī)事件
    LeftSt.TriggerClicked += TriggerClicked;
}


void Update () {

}

//沒有檢測到碰撞信息
void LeftPointOut(object sender, PointerEventArgs e)
{
    //當(dāng)前位置為空
    currentTransform = null;
}
//檢測到碰撞信息
void LeftPointIn(object sender, PointerEventArgs e)
{   
    // 設(shè)置目標(biāo)位置為檢測到的目標(biāo)
    currentTransform = e.target;
}
//扳機(jī)事件
void TriggerClicked(object sender, ClickedEventArgs e)
{
    //如果檢測到目標(biāo)位置
    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);
    }  
}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吓懈,隨后出現(xiàn)的幾起案子歼冰,更是在濱河造成了極大的恐慌,老刑警劉巖耻警,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件隔嫡,死亡現(xiàn)場離奇詭異,居然都是意外死亡甘穿,警方通過查閱死者的電腦和手機(jī)腮恩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來温兼,“玉大人庆揪,你說我怎么就攤上這事》镣校” “怎么了缸榛?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵吝羞,是天一觀的道長。 經(jīng)常有香客問我内颗,道長钧排,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任均澳,我火速辦了婚禮恨溜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘找前。我一直安慰自己糟袁,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布躺盛。 她就那樣靜靜地躺著项戴,像睡著了一般。 火紅的嫁衣襯著肌膚如雪槽惫。 梳的紋絲不亂的頭發(fā)上周叮,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音界斜,去河邊找鬼仿耽。 笑死,一個胖子當(dāng)著我的面吹牛各薇,可吹牛的內(nèi)容都是我干的项贺。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼峭判,長吁一口氣:“原來是場噩夢啊……” “哼开缎!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起朝抖,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤啥箭,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后治宣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體急侥,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年侮邀,在試婚紗的時候發(fā)現(xiàn)自己被綠了坏怪。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡绊茧,死狀恐怖铝宵,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤鹏秋,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布尊蚁,位于F島的核電站,受9級特大地震影響侣夷,放射性物質(zhì)發(fā)生泄漏横朋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一百拓、第九天 我趴在偏房一處隱蔽的房頂上張望琴锭。 院中可真熱鬧,春花似錦衙传、人聲如沸决帖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽地回。三九已至,卻和暖如春腺阳,著一層夾襖步出監(jiān)牢的瞬間落君,已是汗流浹背穿香。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工亭引, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人皮获。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓焙蚓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親洒宝。 傳聞我的和親對象是個殘疾皇子购公,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

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