Cardboard实现VR的目选效果

来源:互联网 发布:网络抽奖 编辑:程序博客网 时间:2024/06/05 00:53

一、首先是下载unity SDK,可以进入Google Cardboard官方网站的开发者指南页面查找下载:https://developers.google.com/cardboard/unity/download
下载后导入到unity中可以查看官方的demo,如下图:


由于Cardboard没什么按键,所以选择之类的事情只能用目选来进行,那怎么实现目选呢?可以想象一下,目选无非就是两部分,a:旋转读条;b、确认选择。
但是有一点,两部分分开来做那很简单啦,但是怎么放到一起呢?
首先,我们先来看看该部分原本给你提供的代码:Teleport.cs

// Copyright 2014 Google Inc. All rights reserved.//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at////     [url=http://www.apache.org/licenses/LICENSE-2.0]http://www.apache.org/licenses/LICENSE-2.0[/url]//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License. using UnityEngine;using System.Collections; [RequireComponent(typeof(Collider))]public class Teleport : MonoBehaviour, ICardboardGazeResponder {  private Vector3 startingPosition;   void Start() {    startingPosition = transform.localPosition;    SetGazedAt(false);  }   void LateUpdate() {    Cardboard.SDK.UpdateState();    if (Cardboard.SDK.BackButtonPressed) {      Application.Quit();    }  }   public void SetGazedAt(bool gazedAt) {    GetComponent<Renderer>().material.color = gazedAt ? Color.green : Color.red;  }   public void Reset() {    transform.localPosition = startingPosition;  }   public void ToggleVRMode() {    Cardboard.SDK.VRModeEnabled = !Cardboard.SDK.VRModeEnabled;  }   public void ToggleDistortionCorrection() {    switch(Cardboard.SDK.DistortionCorrection) {    case Cardboard.DistortionCorrectionMethod.Unity:      Cardboard.SDK.DistortionCorrection = Cardboard.DistortionCorrectionMethod.Native;      break;    case Cardboard.DistortionCorrectionMethod.Native:      Cardboard.SDK.DistortionCorrection = Cardboard.DistortionCorrectionMethod.None;      break;    case Cardboard.DistortionCorrectionMethod.None:    default:      Cardboard.SDK.DistortionCorrection = Cardboard.DistortionCorrectionMethod.Unity;      break;    }  }   public void ToggleDirectRender() {    Cardboard.Controller.directRender = !Cardboard.Controller.directRender;  }   public void TeleportRandomly() {    Vector3 direction = Random.onUnitSphere;    direction.y = Mathf.Clamp(direction.y, 0.5f, 1f);    float distance = 2 * Random.value + 1.5f;    transform.localPosition = direction * distance;  }   #region ICardboardGazeResponder implementation   /// Called when the user is looking on a GameObject with this script,  /// as long as it is set to an appropriate layer (see CardboardGaze).  public void OnGazeEnter() {    SetGazedAt(true);  }   /// Called when the user stops looking on the GameObject, after OnGazeEnter  /// was already called.  public void OnGazeExit() {    SetGazedAt(false);  }   // Called when the Cardboard trigger is used, between OnGazeEnter  /// and OnGazeExit.  public void OnGazeTrigger() {    TeleportRandomly();  }   #endregion}

其实大部分代码我都从头到尾稍稍读了一遍,其实接口已经清楚地给我们放出来了,就是这块代码。代码中有一个SetGazedAt的方法,该方法就是当你水平目视前方的物体算作你选中的物体,官方demo里是当你目视一个cube时把该cube的颜色由红色换为绿色。

二、好的,突破口已经找到了,我们来看看怎么实现旋转读条的效果:
其实很简单,研究过UI的人应该都明白,就是一个很简单的遮罩。
放一个画布canvas,然后创建一个image命名为imageBg作为背景,再创建一个image命名为imageFill作为内容,然后复制一个imageFill,选color属性调成半透明,颜色改成灰色,image Type选择Filled,大小都调合适了。然后就做成了,如图:



三、把Teleport.cs拖到imageBg上,我们再来看刚刚的代码部分,按常理来说,点击选中面板中可以直接添加一个button属性就可以实现,但是我们现在要的是目选,所以就要自己来判断了,其实也不难,也就是一个触发器的问题

public void SetGazedAt(bool gazedAt) {                isStartTime = gazedAt ? true : false;        }


上面这个函数前面加上public
在imageBg下添加一个Event Trigger,添加Pointer Enter和Pointer Exit,分别对应SetGazeAt方法的两个值

在初始化里获取imageFill的image组件,设置fillAmount的初始值为零。
在update里利用计时器来控制旋转读条的快慢,并在读完时刻判断目选的选中状态。
修改后的全部代码如下:

using UnityEngine;using System.Collections;using UnityEngine.UI; public class TeleportGUI : MonoBehaviour, ICardboardGazeResponder {         public float coldTime = 1;        private Image imagefill;        private float timer = 0;        private bool isStartTime = false;        private double minNum = 0.01;        private double maxNum = 0.02;        private bool isNext = false;         public Text index;        int IndexInt = 0;        string IndexStr = "";         // Use this for initialization        void Start () {                 imagefill = transform.Find ("Imagefill").GetComponent<Image> ();                imagefill.fillAmount = 0;                 SetGazedAt (false);         }         void LateUpdate() {                Cardboard.SDK.UpdateState();                if (Cardboard.SDK.BackButtonPressed) {                        Application.Quit();                }        }         public void SetGazedAt(bool gazedAt) {                 isStartTime = gazedAt ? true : false;         }         // Update is called once per frame        void Update () {                                 if (isStartTime) {                        timer += Time.deltaTime;                        imagefill.fillAmount = (coldTime - timer) / coldTime;//从1到0减小                        if (timer >= coldTime) {                                imagefill.fillAmount = 0;                                timer = 0;                                isStartTime = false;                        }                 }                if(!isStartTime) {                                                 timer = 0;                        imagefill.fillAmount = 0;                }                 if (imagefill.fillAmount < maxNum && imagefill.fillAmount >minNum) {                         isNext = true;                 }                 if (isNext) {                         ChooseManageScript.Instance.A_Btn ();                         index = GameObject.Find("IndexBackground").transform.Find ("Index").GetComponent<Text> ();                        IndexInt = int.Parse(index.text);                        IndexInt += 1;                        IndexStr = IndexInt.ToString();                        index.text = IndexStr;                        isNext = false;                }         }         public void TeleportRandomly() {                Vector3 direction = Random.onUnitSphere;                direction.y = Mathf.Clamp(direction.y, 0.5f, 1f);                float distance = 2 * Random.value + 1.5f;                transform.localPosition = direction * distance;        }         #region ICardboardGazeResponder implementation         /// Called when the user is looking on a GameObject with this script,        /// as long as it is set to an appropriate layer (see CardboardGaze).        public void OnGazeEnter() {                SetGazedAt(true);        }         /// Called when the user stops looking on the GameObject, after OnGazeEnter        /// was already called.        public void OnGazeExit() {                SetGazedAt(false);        }         // Called when the Cardboard trigger is used, between OnGazeEnter        /// and OnGazeExit.        public void OnGazeTrigger() {                TeleportRandomly();        }         #endregion }



阅读全文
0 0
原创粉丝点击