美文网首页
VR开发实战HTC Vive项目之拯救金字塔

VR开发实战HTC Vive项目之拯救金字塔

作者: TonyWan_AR | 来源:发表于2017-05-01 23:50 被阅读322次

    一、场景

    二、激光发射逻辑


    EmissionLaser

    using UnityEngine;
    using System.Collections;
    
    public class EmissionLaser : MonoBehaviour {
    
        //开关控制是否发射激光
        public bool Enable;
        //激光发射点
        public GameObject pointer;
        public float thickness = 0.002f;
        Transform previousContact = null;
    
        void Start()
        {
            //创建激光发射点
            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);
            //删除激光发射器的碰撞
            BoxCollider collider = pointer.GetComponent<BoxCollider>();
            GameObject.Destroy(collider);
    
            if (Enable)
            {
                pointer.SetActive(true);
            }
            else
            {
                pointer.SetActive(false);
            }
        }
    
        //开始发射激光
        public void StartEmission()
        {
            pointer.SetActive(true);
            Enable = true;
        }
    
        //停止发射激光
        public void EndEmission()
        {
            pointer.SetActive(false);
            Enable = false;
            //当前是有下一个传递物体,如果有将停止发射激光事件传递给它
            if (previousContact != null)
            {
                ReceiveLaser r = previousContact.GetComponent<ReceiveLaser>();
                if (r != null)
                {
                    r.PointerOut();
                }
                previousContact = null;
            }
        }
    
        void Update()
        {
            //根据Enable来判断是否发射激光
            if(!Enable)
            {
                return;
            }
            Ray raycast = new Ray(transform.position, transform.forward);
            RaycastHit hit;
            bool bHit = Physics.Raycast(raycast, out hit);
    
            float dist = 100f;
    
            //击中物体并且不等于当前击中物体,如果原物体不为空触发PointerOut,新物体触发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();
                }
            }
            //如果没有击中物体,并且原有击中物体,则触发原有物体的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 {
        //引用计数
        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();
            }
        }
    
        //进入低能量状态
        public virtual void LowEnergy()
        {
    
        }
    
        //进入高能量状态
        public virtual void HighEnergy()
        {
    
        }
    }
    
    
    2、接收并发射激光

    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);
        }
    }
    

    四、制作接收和发射激光的预制体

    五、操作狮子旋转

    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并监听属性
            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;
        }
    }
    
    

    六、完善场景布置

    七、效果展示

    相关文章

      网友评论

          本文标题:VR开发实战HTC Vive项目之拯救金字塔

          本文链接:https://www.haomeiwen.com/subject/zadftxtx.html