VR開發(fā)實戰(zhàn)HTC Vive項目之拯救金字塔

一、場景

二、激光發(fā)射邏輯


EmissionLaser

using UnityEngine;
using System.Collections;

public class EmissionLaser : MonoBehaviour {

    //開關控制是否發(fā)射激光
    public bool Enable;
    //激光發(fā)射點
    public GameObject pointer;
    public float thickness = 0.002f;
    Transform previousContact = null;

    void Start()
    {
        //創(chuàng)建激光發(fā)射點
        pointer = GameObject.CreatePrimitive(PrimitiveType.Cube);
        pointer.transform.parent = this.transform;
        pointer.transform.localScale = new Vector3(thickness, thickness, 100f);
        pointer.transform.localPosition = new Vector3(0f, 0f, 50f);
        pointer.transform.rotation = new Quaternion(0, 0, 0, 0);
        //刪除激光發(fā)射器的碰撞
        BoxCollider collider = pointer.GetComponent<BoxCollider>();
        GameObject.Destroy(collider);

        if (Enable)
        {
            pointer.SetActive(true);
        }
        else
        {
            pointer.SetActive(false);
        }
    }

    //開始發(fā)射激光
    public void StartEmission()
    {
        pointer.SetActive(true);
        Enable = true;
    }

    //停止發(fā)射激光
    public void EndEmission()
    {
        pointer.SetActive(false);
        Enable = false;
        //當前是有下一個傳遞物體,如果有將停止發(fā)射激光事件傳遞給它
        if (previousContact != null)
        {
            ReceiveLaser r = previousContact.GetComponent<ReceiveLaser>();
            if (r != null)
            {
                r.PointerOut();
            }
            previousContact = null;
        }
    }

    void Update()
    {
        //根據(jù)Enable來判斷是否發(fā)射激光
        if(!Enable)
        {
            return;
        }
        Ray raycast = new Ray(transform.position, transform.forward);
        RaycastHit hit;
        bool bHit = Physics.Raycast(raycast, out hit);

        float dist = 100f;

        //擊中物體并且不等于當前擊中物體,如果原物體不為空觸發(fā)PointerOut,新物體觸發(fā)PointIn事件。
        if (bHit && previousContact != hit.transform)
        {
            ReceiveLaser r;
            if (previousContact!= null)
            {
                r = previousContact.GetComponent<ReceiveLaser>();
                if (r != null)
                {
                    r.PointerOut();
                }
            }

            previousContact = hit.transform;
            r = previousContact.GetComponent<ReceiveLaser>();
            if (r != null)
            {
                r.PointerIn();
            }
        }
        //如果沒有擊中物體,并且原有擊中物體,則觸發(fā)原有物體的PointerOut事件,并將previousContact至空
        if (!bHit)
        {
            if(previousContact != null)
            {
                ReceiveLaser r = previousContact.GetComponent<ReceiveLaser>();
                if (r != null)
                {
                    r.PointerOut();
                }
                previousContact = null;
            }
        }
        if (bHit && hit.distance < 100f)
        {
            dist = hit.distance;
        }

        pointer.transform.localScale = new Vector3(thickness, thickness, dist);

        pointer.transform.localPosition = new Vector3(0f, 0f, dist / 2f);
    }
}

三、接收激光

1、父類接收激光腳本

ReceiveLaser

using UnityEngine;
using System.Collections;

public class ReceiveLaser : MonoBehaviour {
    //引用計數(shù)
    int ReferenceCount = 0;
    // Use this for initialization
    void Start () {
        
    }

    //有激光擊中
    public void PointerIn()
    {
        ReferenceCount++;
        if(ReferenceCount > 0)
        {
            HighEnergy();
        }
    }

    //激光離開
    public void PointerOut()
    {
        ReferenceCount--;
        if (ReferenceCount <=0 )
        {
            LowEnergy();
        }
    }

    //進入低能量狀態(tài)
    public virtual void LowEnergy()
    {

    }

    //進入高能量狀態(tài)
    public virtual void HighEnergy()
    {

    }
}

2、接收并發(fā)射激光

ReceiveAndEmissionLaser

using UnityEngine;
using System.Collections;
public class ReceiveAndEmissionLaser : ReceiveLaser
{
    public EmissionLaser[] EmissionLasers;

    public override void HighEnergy()
    {
        foreach (EmissionLaser EmissionLaser in EmissionLasers)
        {
            EmissionLaser.StartEmission();
        }
    }

    public override void LowEnergy()
    {
        foreach (EmissionLaser EmissionLaser in EmissionLasers)
        {
            EmissionLaser.EndEmission();
        }
    }
}
3、接收激光后開門

ReceiveAndOpenDoor

using UnityEngine;
using System.Collections;

public class ReceiveAndOpenDoor : ReceiveLaser
{
    public Transform[] Doors;
    bool HasEnergy = false;

    void FixedUpdate()
    {
        if(HasEnergy)
        {
            foreach(Transform tr in Doors)
            {
                tr.position = Vector3.Lerp(tr.position , new Vector3(tr.position.x,-10, tr.position.z),Time.fixedDeltaTime);
            }
        }
    }

    public override void HighEnergy()
    {
        HasEnergy = true;
    }
}

4、接收后通過關卡勝利

ReceiveAndWin

using UnityEngine;
using System.Collections;

public class ReceiveAndWin : ReceiveLaser
{
    public GameObject Win;
    public override void HighEnergy()
    {
        Win.SetActive (true);
    }
}

四、制作接收和發(fā)射激光的預制體

五、操作獅子旋轉

using UnityEngine;
using System.Collections;

public class RotateLion : MonoBehaviour
{
    SteamVR_LaserPointer SteamVR_LaserPointer;
    SteamVR_TrackedController SteamVR_TrackedController;
    Transform pointTransform;
    GameObject currentCatch;
    bool isTrigger;


    // Use this for initialization
    void Start()
    {
        //獲取SteamVR_LaserPointer和SteamVR_TrackedController并監(jiān)聽屬性
        SteamVR_LaserPointer = GetComponent<SteamVR_LaserPointer>();
        SteamVR_LaserPointer.PointerIn += PointerIn;
        SteamVR_LaserPointer.PointerOut += PointerOut;
        SteamVR_TrackedController = GetComponent<SteamVR_TrackedController>();
        SteamVR_TrackedController.TriggerClicked += TriggerClicked;
        SteamVR_TrackedController.TriggerUnclicked += TriggerUnclicked;
    }

    void FixedUpdate()
    {
        if (pointTransform != null && isTrigger)
        {
            pointTransform.rotation = Quaternion.AngleAxis(pointTransform.rotation.eulerAngles.y + 0.5f,Vector3.up);
        }
    }

    void PointerIn(object sender, PointerEventArgs e)
    {
        //判斷是不是tag為Lion,如果不是就不設置標志。
        if (e.target.gameObject.tag == "Lion")
        {
            pointTransform = e.target;
        }
    }

    void PointerOut(object sender, PointerEventArgs e)
    {
        pointTransform = null;
    }

    void TriggerClicked(object sender, ClickedEventArgs e)
    {
        isTrigger = true;
    }

    void TriggerUnclicked(object sender, ClickedEventArgs e)
    {
        isTrigger = false;
    }
}

六、完善場景布置

七、效果展示

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

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

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