虚拟现实大作业——VR游乐园(无设备开发)之3.3.游乐设备选择场景搭建

1. 射线控制视频播放

  • 继续编辑GameItem脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Video;
using VRTK;
using System.IO;

public class GameItem : MonoBehaviour
{

    private VideoPlayer m_VideoPlayer;

    private void Awake()
    {
        m_VideoPlayer = GetComponent();
        // 获取按钮圆盘
        GameObject.Find("ControllerRight").GetComponent().TouchpadReleased += GameItem_TouchpadReleased;
        GameObject.Find("ControllerLeft").GetComponent().TouchpadReleased += GameItem_TouchpadReleased;
    }
    //圆盘按钮抬起
    private void GameItem_TouchpadReleased(object sender, ControllerInteractionEventArgs e)
    {
        m_VideoPlayer.Pause();
    }

    //设置视频名称
    public void SetVideoName(string videoName)
    {
        m_VideoPlayer.url = GetVideoPath(videoName);
    }

    //获取视频路径
    private string GetVideoPath(string videoName)
    {
        return Application.dataPath + "/StreamingAssets/" + videoName + ".mp4";
    }

    private void OnTriggerEnter(Collider other)
    {
        //代表文件不存在
        if (File.Exists(m_VideoPlayer.url) == false) return;
        m_VideoPlayer.Play();
    }

    private void OnTriggerExit(Collider other)
    {
        m_VideoPlayer.Pause();
    }
}


2. 完善射线碰撞检测问题

继续编辑GameItem脚本,让射线只对当前游乐项目起作用

  • 在GameItem脚本中添加以下内容
public int Index;
private void Update()
{
    if (Index == GameItemSpawn.Instance.Index)
    {
        GetComponent().enabled = true;
        GetComponent().material.color = Color.white;
    }
    else
    {
        GetComponent().enabled = false;
        GetComponent().material.color = Color.gray;
    }
}
  • 编辑GameItemSpawn脚本Awake部分
private void Awake()
{
    Instance = this;
    m_Angle = 360.0f / m_GameItemMatArr.Length;
    for (int i = 0; i < m_GameItemMatArr.Length; i++)
    {
        GameObject go = Instantiate(go_GameItem, transform);
        go.transform.localEulerAngles = new Vector3(0, i * m_Angle, 0);
        go.GetComponentInChildren().material = m_GameItemMatArr[i];
        go.GetComponentInChildren().SetVideoName(m_GameItemMatArr[i].name);
        go.GetComponentInChildren().Index = i;
    }
}
  • 次试运行项目,测试射线在碰到其他项目的时候还会不会变色

3. 场景加载界面创建

实现选中SELECT按钮之后切换场景

  • 在Canvas下创建一个空物体修改名称为LoadingPanel,并填充至与Canvas一样大小,再在LoadingPanel下创建一个Image子物体修改名称为bg,一样填充至一样大小,Source Image选为Loading
  • 同理再创建一个Image,修改命名为img_LoadingBar,并进行设置

因为后续要将LoadingBar从0到1进行填充表示载入过程,所以要进行相关设置

修改图片类型为填充的,填充方法为水平方向的,水平方向从左到右

  • 将img_LoadingBar复制一份(Ctrl+D),修改名称为img_LoadingBarOut,Source Image为LOADING_BAR_OUTER作为外边框
  • 在Scripts下的UI文件夹中创建LoadingPanel.cs脚本管理加载界面,同时挂载到LoadingPanel物体上
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using DG.Tweening;
using UnityEngine.UI;
using UnityEngine.SceneManagement;

public class LoadingPanel : MonoBehaviour
{

    public static LoadingPanel Instance;
    private Image img_LoadingBar;
    private AsyncOperation m_Ao;
    private bool m_IsLoad = false;

    private void Awake()
    {
        Instance = this;
        // 将缩放设置为0,相当于隐藏起来
        transform.localScale = Vector3.zero;
        img_LoadingBar = transform.Find("img_LodingBar").GetComponent();
    }

    public void LoadScene()
    {
        // 将加载界面显示出来
        transform.DOScale(Vector3.one, 0.3f).OnComplete(() =>  // 动画播放完再开始协程
        {
            StartCoroutine("Load");
        });
    }

    // 使用异步协程的方式缓解卡顿问题
    IEnumerator Load()
    {
        // 显示的进度
        int displayProgress = -1;
        // 到达的进度
        int toProgress = 100;

        while (displayProgress < toProgress)
        {
            displayProgress++;   // 第一次执行的时候就是0
            ShowProgress(displayProgress);

            if (m_IsLoad == false)
            {
                // 异步方式加载场景,根据下标确定要加载的场景,因为之前有MainScene和StartScene两个场景,所以加载游乐项目时要在原来下标基础上加2
                m_Ao = SceneManager.LoadSceneAsync(2 + GameItemSpawn.Instance.Index);  
                // 防止进度未到达100场景就跳转
                m_Ao.allowSceneActivation = false;   // 尽管场景加载完毕也不允许显示
                m_IsLoad = true;
            }
            yield return new WaitForEndOfFrame();

        }
        // 进度到达100之后场景才跳转
        if (displayProgress == 100)
        {
            m_Ao.allowSceneActivation = true;
            // 场景加载完之后停掉协程
            StopCoroutine("Load");
        }
    }

    // 显示进度 
    private void ShowProgress(int progress)
    {
        img_LoadingBar.fillAmount = progress * 0.01f;  // fillAmount的范围是0到1,所以需要成0.01
    }
}

  • 给GameItemSelectPanel脚本中的Init部分添加点击监听事件
private void Init()
{
    txt_Title = transform.Find("txt_Title").GetComponent();
    btn_Forward = transform.Find("btn_Forward").GetComponent
  • 按照GameItemSpawn中GameItem数组中的顺序将各个游乐项目场景添加进去


虚拟现实大作业——VR游乐园(无设备开发)之3.3.游乐设备选择场景搭建_第1张图片
虚拟现实大作业——VR游乐园(无设备开发)之3.3.游乐设备选择场景搭建_第2张图片

  • 将GameItemSpawn的z轴位置调整为20(可以自己调整,只要不是0),防止游乐项目图片和UI界面重叠导致闪屏

你可能感兴趣的:(虚拟现实大作业)