原文链接:点击打开链接

作者是用iPhone适配的,我是用的Android手机且由于SDK版本的关系所以会有些小细节不一样。

游戏工程地址:忍者飞镖

GoogleVR SDK for Unity:SDK 或 https://developers.google.com/vr/

欢迎……来到三维空间!

可以很负责任的说每个人都在期待着虚拟现实体验,自从现代经典电影《割草者》的上映,向我们预示了一个可喜的未来……额,通过虚拟现实

我们可以拥有心灵感应类似的力量。

在这篇指导内,你会通过谷歌纸盒学习将一个简单的Unity游戏变成一个VR游戏来帮助人类准备好心灵感应的能力和虚拟现实。此文,你会学习到:

1.集成一个VR摄像机到你的工程

2.修改UI元素让它们工作在VR模式

3.让按钮在VR模式下可以选中

4.在运行中以编程的方式完成VR和普通模式的切换

Note:在写的时候,通过VR拥有思维控制和成为超人一般的能力不是一个可行的科技,不管《割草者》展示给我们的那些。因此,直到有了思维控制API,

坚持掌握先驱者(VR技术~_~)。

什么是谷歌纸盒?

原理上创建一个VR体验是很直接的。替换掉显示在你屏幕上的单个图片,变成两张图片~

他们来自两个摄像机隔开一点距离放置,用户通过左眼看左边的图片,反之亦然,创建出有深度的景象。

而且,通过正确的传感器数据,你可以检测到用户面朝哪个方向。结合到你创建的3D场景,你会得到一个沉浸式的体验。

通常,这需要一些相当复杂精妙的硬件去显示两个高分辨率的图像,连同追踪用户的头部,把所有的内容放进一个小且足够明亮设备中不会伤害你的颈部。

然而,结果证明这样一个高科技先进设备正是你口袋的arm架构的手机。几乎所有的智能手机,它是纸盒之前的idea。你的手机有显示和传感器可以把他们变成

一个可用的VR设备,只需要一个纸盒子和两个塑料透镜。

开始吧

Note:你需要使用不少的UnityGUI的一些知识,如果你从来没有接触过,你可能需要学习一下UGUI

为了开始制作你自己的VR游戏,你需要以下内容:

1.5.x版本的Unity开发套件

2.一部智能手机,iPhone 5或Android 4.1以后。

3.一个装手机的VR设备

Note:如果你对Unity不熟悉也不了解相应借口,你可以去Unity官网进行学习。

没有VR设备我能否进行开发?

当然阔以,运行在手机上就是这样滴:

当播放的时候如果你盯住屏幕,你可以近似的得到一个3D的体验。如果你移动你的手机,通过绑住你的头你可以控制它,模拟点击通过敲击屏幕(装进盒子

了怎么敲? 所以最好还是有个蓝牙手柄……当然不装进去点着玩儿也不错)~

尽管你可以通过使用VR一体机玩游戏去感受它是什么感觉,但并不意味着你应该这样做。有点像吃巧克力和听别人说巧克力是什么味道。当然,你会得到一般

的印象,但并不一样。

长话短说:如果你没有耐心等到VR设备的到来,你仍然可以学习这篇向导,但有正确的装备去操作你会得到更多。

例子游戏——忍者回旋镖

花点儿时间玩玩你的例子游戏,下载链接在文章开始处。

接下来打开你的Unity,选择Open Project打开StarterNinja文件夹,然后打开NinjaAttack工程。

选择Assets目录下的MainScene打开,然后开始玩游戏。

左边是你的忍者,怪物会穿过屏幕,点击屏幕上的任何地方发射忍者飞镖打倒他们!打倒20个怪物你就赢了,但是如果怪物到达了左边的红色区域,你就输了。

从谷歌VR的SDK开始

首先你需要下载SDK,文章开始处有找寻相应SDK的方法,自行下载~

接下来导入到你的工程,从Unity的菜单处点击Asset\Import Package\Custom Package……之后选择GoogleVRForUnity.unitypackgage,也就是你下载的SDK。

确认所有的都选中了,去掉选中DemoScenes文件夹(就是一些例子导不导入随意),然后点击导入按钮。

乘热打铁

为了让你的游戏成为VR模式,你需要展示一些快速的暗招。

在GoogleVR\Prefabs文件夹中,将GvrViewerMain预制体拖到Hierachy中。设置它的坐标几乎是你忍者角色的坐标(-5.53, 1.13, 0.122)

和Y轴旋转90度

你会意识到这个坐标比忍者的中心位置高一点,实际上你是通过它的眼睛看出去的。GvrViewerMain默认以第一个主相机为目标来进行相机的分身

处理所以你需要将主相机也调整到对应的位置,让主相机刚好渲染出角色视角看到的场景(可以通过修改之前的相机到Perspective模式,推荐新建

一个相机然后关闭正交相机,之后动态切换相机的时候还需要默认的相机)。

现在在你的编辑器中运行游戏,你应该看到场景被重新组装成了3D的!如果此时你按住Alt键然后晃动你的鼠标,相机会像你转动你的头一样运动。

把这个场景在你的安卓设备上跑起来

在你的编辑器里运行游戏是好的,但是我最后一次检查了没有合适的VR设备和好的电脑这样运行起来是痛苦的,因此我们工作在手机上。

1.选中File\Build Settings——Android应该被选择为你的默认平台

2.点击Player Settings到达inspector界面

3.在Resolution and Presentation下选择Default Orientation为Landscape Left

4.在Other Settings里把Bundle Identifier改成合适的组织名称(com.xxx.xxxx   默认的编译会报错)

  

连接上你的手机和电脑之后,选择Build and Run之后选择输出文件夹,随意路径。

Unity会导出你的工程,之后会将会发布到你的手机上,装进你的VR设备调节好视距之类的就开始体验吧。

Note:如果发布到手机,手机启动应用时出现了什么错误,你可以用Android的IDE查看相应的log信息,或者adb logcat > d:\logcat.txt

将运行的log抓取出来然后判断是哪里出错了。

重新制作这个游戏!

总的来说可以观看你的游戏世界是很棒的,但是你需要玩儿它。独特的讲,你想要往面朝的地方发射忍者飞镖,那是你刚开始玩儿游戏所体会到的。

UI层面,纸盒支持一个按钮(我用的淘宝上买的,有蓝牙手柄~),会感受到限制,但是结合到你头部的动作跟踪,它允许你更加完整的交互。

在游戏中,你会检测用户的GvrViewer.Instance.VRModeEnabled属性。你会检查GvrViewer.Instance.Triggered按钮是否

按下的属性。如果都为true,你就会在面朝的方向发射一个飞镖。

打开你的 NinjaStarLauncher.cs 脚本,你可以在GameLogic 游戏物体上找到。

创建一个新的私有变量:

private Vector3 _vrShooterOffset;

在   Start()方法中初始化它:

_vrShooterOffset = new Vector3(0.0f, -0.4f, 1.0f);

用以下代码替换你的 Update()

void Update () {//1 if (GvrViewer.Instance.VRModeEnabled && GvrViewer.Instance.Triggered && !_gameController.isGameOver) {  GameObject vrLauncher = GvrViewer.Instance.GetComponentInChildren<GvrHead>().gameObject;// 2LaunchNinjaStarFrom(vrLauncher, _vrShooterOffset);} else if (!GvrViewer.Instance.VRModeEnabled && Input.GetButtonDown("Fire1") && !_gameController.isGameOver) {// This is the same code as beforeVector3 mouseLoc = Input.mousePosition;Vector3 worldMouseLoc = Camera.main.ScreenToWorldPoint(mouseLoc);worldMouseLoc.y = ninja.transform.position.y;ninja.transform.LookAt(worldMouseLoc);LaunchNinjaStarFrom(ninja, _shooterOffset);}
}

它你会让你的游戏运行起来,看看Update方法做了啥:

1.首先检测你是否处于VR模式且用户点击了按钮被单例模式的GvrViewer.Instance 检测属性的变化。

2.之后你可以调用LaunchNinjaStarFrom() 方法去实例化一个忍者飞镖,传进去两个参数:

A.首先是你的头部游戏对象,谷歌VR库为你准备好了,应该已经指向了正确的方向.

B.第二个是一个轻度的偏移,因此这个方法实例化一个忍者飞镖在你的前面一点下方一点,看起来更加的正常,总不希望飞镖

从你的眼睛里面发射出来吧?很酷,但很奇怪~

你的飞镖在被生成出来的时候就注定要在你面朝的方向飞走,它会朝着正确的地方开火~

换个方式尝试!在这个点上,你可以旋转你的头部去射击坏人,输还是赢逻辑仍然有用。

修复Game Over菜单

正如你所观察到的那样,当游戏结束的时候留下的还是之前的游戏结束菜单。没有以正确的3D模式去显示,所以没法去点击它。

游戏当前使用的是画布显示——UGUI里面的——去显示Game Over,总是显示在游戏窗口的最上层。

这个画布对很多的游戏都是很实用的,它会自动缩放自身去适应你的屏幕,不管你的游戏摄像机在做什么,它对不同的屏幕尺寸是友好的。

但在这种情况下,你需要一个GUI画布存在于世界坐标中,会被3D场景渲染,同样因为你不想让它随着摄像机的移动而没有变化。

你想要你的用户可以朝上看朝下看,看向不同的UI元素通过点击按钮激活它。

创建一个新的Canvas

在Hierachy中选中并复制一份GameOverCanvas

将副本重命名为VRGameOverCanvas,为了与原始的作区分把其子对象GameOverTxt重命名成 VRGameOverTxt.

                                                                                   

VRGameOverCanvas的组件Canvas中,把Render Mode变成World Space

Rect Transform组件中,改变属性Position(-2.24, 1.1, 0.07),和Y Rotation90.

最后,把X和Y的缩放为0.009.所有设置好了之后为像这样滴:

之后,你应该看见两个画布会重叠(游戏没有运行的时候):

这些值是从哪里来的?老实说,我也是瞎搞了很久直到把他们弄起来在纸盒内看起来比较好。

有时候编程更像是一门艺术而不是科学……

支持两种画布

接下来,你要修改GameController.cs去意识到两种画布的存在。打开脚本并修改,这个脚本同样挂载在GameLogic游戏物体上。

在类中加上这两个公有变量:

public Canvas VRGameOverCanvas;
public Text VRGameOverTxt;

GameOver()
方法替换为:

public void GameOver(bool didIWin) {isGameOver = true;_didIWin = didIWin;string finalTxt = (_didIWin) ? "You won!" : "Too bad";if (GvrViewer.Instance.VRModeEnabled) {VRGameOverCanvas.enabled = true;VRGameOverTxt.text = finalTxt;} else {gameOverCanvas.enabled = true;gameOverTxt.text = finalTxt;}
}

这会显示合适的画布和文字对象,取决于你是否处于VR模式 ( GvrViewer.Instance.VRModeEnabled ).

在你保存了你的脚本之后,你需要为你的新变量赋上正确的值。

找到GameController 脚本,像下图一样赋值。

Note:你是否在想你为什么要支持两种画布而不是只是替换到现在有的呢?因为最终你需要支持两种模式,调整状态!

如果你现在运行你的游戏,你会看见合适的VR模式游戏结束界面。可以朝上看朝下看,看不同的部分,当你点击Play Again按钮时就会消失。

Note:至少,理论上看起来应该是这样的。

练习中,5.3.4p2的Unity会有一个BUG,世界坐标系的GUI画布不会渲染到RenderTexture(这啥?),所以谷歌的SDK使用扭曲修正——你在

两个摄像机中看见的鱼眼效果。

作为一个暂时的变通方案,你可以在GvrViewerMain对象的Gvr Viewer组件上改变Distortion Correction为None。

这意味着你可能会看见轻微的扭曲,当你把游戏放入你的VR设备区看的时候,但至少你能够看见你的GUI。

添加凝视输入

幸运滴,Unity内置支持相机中心点作为一个鼠标,当使用世界坐标系的GUI的时候,但你需要提供一个附加的脚本让其在VR模式下工作。

首先,把你的主相机放置在GvrViewerMain对象的子节点上:

选择你的VRGameOverCanvas 对象,你会看见Event Camera选项,将VR Main Camera选中(之前你修改的主相机)。

点击在Hierachy中的EventSystem  对象,添加GazeInputModule 脚本。这是一个让UGUI明白谷歌VR相机是怎么工作的。

选中VR Mode Only选项框,因为你只是想要工作在VR模式而不是普通的版本。

最终把你的Gaze InputModule往上移保证它的优先级,最终看起来会像这样:

现在尝试一下!当你聚焦到PlayAgain按钮上,它应该变成绿色,然后点击一下屏幕就会开始新的游戏!

细微的游戏调整

因此,也许你发现在VR模式的这个版本很难。这个部分是因为在VR模式下你减小了视野,在你看向错误的方向的时候敌人也更容易溜走。

同时,你不能和以前一样快速的转变你的方向去瞄准,物理上被你的脖子转动速度所限制。

你不想让选择玩VR模式的玩家遭罪!所有你怎么修正这个呢?

额,我会建议减少敌人的速度。你会怎么想?

选中你在Prefab文件夹内的EvilSlimeEnemy预制体,打开挂载上面的EnemyMover.cs脚本。加上以下代码,

正好在之前设置thisSpeed的地方:

if (GvrViewer.Instance.VRModeEnabled) { thisSpeed *= 0.85f;
}

这会让你的敌人更集中一点,如果你想让它们空出一些空间,找到 EnemySpawner.cs
——它挂载在你的 GameLogic游戏物体上——添加以下代码行在 SetNextLaunch()方法中,

在你设置了launchInterval之后:

if (GvrViewer.Instance.VRModeEnabled) { launchInterval *= 1.1f;
}

这会让你的VR游戏更加容易尝试——足够让你的玩家选择这样玩儿不感到坑爹。

修改屏幕上显示的分数
其他的UI元素你需要在屏幕上定位的是分数对象,你将尝试轻微的不同方式。仍然需要出现在在合适的VR模式,你想要修改它

在你的摄像机看向任何地方的时候。

想象把你的分数投影在一片持续运动的玻璃上,因此它总是与你看向的地方保持2米远的距离。这是你将要创建的效果。

你将要实现它通过另一个渲染在3D世界的画布,将它变成GoogleVR Head 对象的子物体(这是原文作者的实现方式,我没弄成

不知道原文作者的效果是不是分数面板跟着头一起动的,我的是固定在一个地方的。因为它的SDK貌似是有一个相机的,可以放置到

头部跟踪,而我的SDK是没有相机,通过渲染主相机达到的,没法去跟踪头部运动~)。

然后在GvrViewerMain中右击新建一个Canvas,重命名为VRScoreCanvas将Render Mode变为World Space。

设置以下值:

1.Position:(0,1,2.5)

2.Width:400, Height: 100

3.Rotation:(0,0,0)

4.Scale:(0.0115, 0.0115, 1)

当你设置好了之后,应该像下面一样:

在你的VRScoreCanvas右击添加UI\Text子物体,重命名为VRScoreTxt。把锚点设置为左上方,Position的值为(150, -65, 0)和Width为60。

在文本组件中,设置字体大小为18对其方式为右对齐,值为999,完成后像这样:

它也许看起来很奇怪的位于你屏幕的中央,但是在VR模式,你看见的比你实际世界要少很多,所以结果上这文字是很靠近你的视野边界的。

自由调试让它看起来在你的手机上合适。

接下来添加这个物体来显示你的分数,过程和你显示GameOver文字很类似。

打开GameController.cs然后添加一个公有变量:

public Text VRScoreTxt;

然后,你会每次更新你的VRScoreTxt去更新分数,在ResetGame()方法中添加这一行,刚好在你更新scoreTxt之后:

VRScoreTxt.text = "--";

接下来添加这一行在GotOne()方法里面,刚好在你更新scoreTxt之后:

VRScoreTxt.text = "" + _currScore;

保存你的脚本,回到Unity你会发现GameLogic游戏对象上的GameController组件有了空处,将VRScoreTxt赋值。
                                                             

再次运行你的游戏,你会看见分数出现在了你的视野中,并且跟随你的头部运动。

进入和跳出VR模式

自从你的游戏工作在普通模式和VR模式,你需要让用户有能力去切换他们。

一个UI很直接就可以实现,你添加一个简单的按钮,可以切换VR模式和普通模式。福利来了,谷歌VR的SDK自己有一个返回按钮,你可以

用它来返回普通模式。

试一下!

首先,你将要添加一些代码去切换VR模式。选中GameLogic游戏物体,点击添加组件,新增CardboardSwapper脚本(我新增这个脚本会编译不过,

所以搞成了Changer脚本,不知道是不是命名被sdk的哪里重复了)。

打开,然后替换以下代码:

public class CardboardSwapper : MonoBehaviour {public GameObject[] cardboardObjects;public GameObject[] monoObjects;// Turn on or off VR modevoid ActivateVRMode(bool goToVR) {foreach (GameObject cardboardThing in cardboardObjects) {cardboardThing.SetActive(goToVR);}foreach (GameObject monoThing in monoObjects) {monoThing.SetActive(!goToVR);}GvrViewer.Instance.VRModeEnabled = goToVR;// Tell the game over screen to redisplay itself if necessarygameObject.GetComponent<GameController>().RefreshGameOver();}public void Switch() {ActivateVRMode(!GvrViewer.Instance.VRModeEnabled);}void Update () {if (GvrViewer.Instance.BackButtonPressed) {Switch();}}void Start() {ActivateVRMode(false);}
}

这个类中最重要的方法是ActivateVRMode当你改变了GvrViewr.Instance.VRModeEnable,就激活了VR模式。

剩下的逻辑就是激活或关闭在场景中不同的游戏物体,取决于你是否在VR模式。调用Start()方法中调用ActivateVRMode(false)

就会让你的游戏以普通模式开始。

你同样会意识到当点击返回按钮时会调用Switch()方法,你可以在编辑器中用esc键模式模拟GvrViewer.Instance.BackButtonPressed,一个

让你毫无疑问很趁手的测试特性。

你需要添加更多的一些游戏逻辑到你的GameController脚本里面让其正确选择游戏结束的模式。

打开GameController.cs添加如下方法:

public void RefreshGameOver() {gameOverCanvas.enabled = false;VRGameOverCanvas.enabled = false;if (isGameOver) {GameOver(_didIWin);}
}

保存所有,然后回到Unity给两种游戏物体数组赋值,就是你创建的转换开关类,挂在GameLogic上:
                                                  
最后,你需要添加一个按钮在画布上供用户点击。节约时间,我已经准备好了。

在Prefabs文件夹下找到CardboardButton推到Canvas的子节点,设置Position(-50, 50, 0):

在你按钮的游戏物体的下方添加点击时间去调用CardboardSwapper.Switch()方法,如下:

再次尝试你的游戏,就可以切换场景了:

祝贺!你像个老板样切换模式了!

怎么通过Unity和谷歌纸盒做一个VR游戏?(译)相关推荐

  1. scratch做简单跑酷游戏_腾讯游戏学院专家:做一个多线程游戏框架可以多简单?...

    导语 如何做一个多线程游戏框架?腾讯游戏学院专家Tao将在本文通过一个demo来说说游戏逻辑的多线程化. 众所周知现在各种游戏终端的发展十分迅猛.其中一个共同的特征是"多核化",由 ...

  2. 用 JS 做一个数独游戏(二)

    用 JS 做一个数独游戏(二) 在 上一篇博客 中,我们通过 Node 运行了我们的 JavaScript 代码,在控制台中打印出来生成好的数独终盘.为了让我们的数独游戏能有良好的体验,这篇博客将会为 ...

  3. python手机版做小游戏代码大全-Python大牛手把手教你做一个小游戏,萌新福利!...

    原标题:Python大牛手把手教你做一个小游戏,萌新福利! 引言 最近python语言大火,除了在科学计算领域python有用武之地之外,在游戏.后台等方面,python也大放异彩,本篇博文将按照正规 ...

  4. 做一个FLASH游戏你需要掌握的东西【实用】

    做一个FLASH游戏你需要掌握的东西 作者:jianzhong 一直想着什么时间好好做一个像样点的游戏,于是刻意的开始去了解FLASHGAME的相关资料,在这里把自己在整个制作和收集过程中的一些感觉使 ...

  5. 单枪匹马:4年只做一个iOS游戏 收入破千万美元

    2011 年,一款叫做<Tiny Wings>的手游被苹果推荐为最佳 iPhone 游戏,对手游市场有所了解的同学一定会赞同<Tiny Wings>是过去几年中全球知名度仅次于 ...

  6. 用 Python 做一个 H5 游戏机器人

    原文地址:Creating An HTML5 Game Bot Using Python 原文作者:vesche 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- ...

  7. 使用PixiJS做一个小游戏

    PixiJS PixiJS使用WebGL,是一个超快的HTML5 2D渲染引擎.作为一个Javascript的2D渲染器,Pixi.js的目标是提供一个快速的.轻量级而且是兼任所有设备的2D库. 官方 ...

  8. dx绘制2d图像_【教程】使用DX9做一个2D游戏(1)

    本文最先发表在贴吧,现在整理到此处,之后所有更新将在这里进行. by Chu @ XDU 2012/11/25 版权所有,禁止用于商业用途. 转载请注明出处. 用DX9做一个2D游戏显然不是一件容易的 ...

  9. 用pygame做一个追逐游戏

    大家好呀,今天来做一个追逐游戏 1.使用鼠标操作 2.左键换颜色(随机) 3.滚轮调整球体大小(往上调大,往下调小) 4.右键清空屏幕 import sys import pygame as p fr ...

最新文章

  1. Windows上erl.exe的CPU使用率很高的问题【未解决】
  2. map/set/object/array对比
  3. 【干货】Sketch+Keynote双剑合璧:5步快速制作移动动效
  4. Individual Project
  5. C语言register关键字——最快的关键字
  6. 点击链接,执行.py脚本,cgi脚本,浏览器中没有显示解析后的web页面,而是.py文件本身的代码内容...
  7. 大数据常用数据库汇总
  8. PHP面向对象(OOP)----分页类 1
  9. Jmeter模拟多用户同时登陆
  10. 比特大爆炸为啥老显示服务器满,《有可能是史上最长停服维护公告》
  11. [转]asp实现数据库导出excel文件
  12. 一步一步搭建ZooKeeper + Mesos + Marathon平台管理Docker集群
  13. 【BZOJ 4551】【TJOI2016】【HEOI2016】树
  14. 便捷式计算机无线功能按钮,便携式wifi热点怎么用 便携式WI-FI热点使用步骤【详解】...
  15. python多元非线性回归模型_Python 非线性回归 - 树懒学堂
  16. SQLException:no opration allowed after statement closed问题排查
  17. etc2 纹理压缩_ETC纹理的紧缩压缩
  18. 802.11-2020协议学习__$12-Security__$12.3.2-WEP__1
  19. [Zer0pts2020]easy strcmp
  20. 渗透测试实用浏览器插件推荐

热门文章

  1. 扫地机器人朋友圈文案_最近,一台不务正业的愚大宝扫地机器人火遍朋友圈
  2. android gms认证之run host test,Android GMS认证项总结
  3. 驯服最难以捉摸的野兽──创新
  4. matlab 实现信号的微分和积分
  5. UPC 小澳的葫芦 (最短路+01分数规划 )
  6. Redisson 限流器 RRateLimiter的使用
  7. python做积分_利用python求积分的实例
  8. 2021-01-22学习记录 || 通过二维数组初始化窗体并进行代码重构
  9. 基于VS+Opencv2.4.10的微信跳一跳辅助工具
  10. 石子合并问题java_动态规划求石子合并问题