Cardboard实现VR的目选效果

一、首先是下载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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值