开发VR游戏首先要选择一个合适的平台。目前可供选择的平台不多, Google的Cardboard和Oculus Rift等头戴式显示设备都是可供选择的对象。但Cardboard的价格低廉,市场占有率更高,用它来作为移动端进行开发更为划算一些。当然,选择其一并不代表我们舍弃了其它开发平台的优点,同时Unity3D游戏引擎拥有跨平台的特性,对项目经过简单的修改便可将VR项目移植到PC或者其他平台中。
使用Unity3D开发VR游戏十分便捷。首先在于如场景、模型等丰富的素材资源,开发者们无需再为美工建模这些相对耗时间的工作而困扰。其次在于便捷的引擎支持,Oculus Rift、Google Cardboard和HTC Vive等产品均提供了对于Unity3D引擎的支持,只需将官方提供的插件包导入到目标项目中,便可使用相应的VR产品了。随着Unity5.3版本的发布,Unity增强了对VR开发的兼容性,在项目设置中我们可以直接选择使用Oculus或是Open VR进行开发。
下面就以一款简单的VR弹球游戏为例子,谈谈使用Unity3D游戏引擎开发VR游戏的流程。
先说说VR弹球游戏的规则。和传统的弹球游戏一样,在VR弹球游戏中有两个玩家,一个是用户,另一个则是AI。玩家分别控制己方的一块弹球板,当弹球碰到弹球板的时候,球则会反弹回去。如果一方没有成功反弹弹球的话则该方失败。
那么对于这款VR弹球游戏,具体应该怎样开发呢?
在确定了开发平台之后,我们需要在Unity中导入相关的SDK。如选用Oculus Rift则导入Oculus Rift的SDK,选用Google Cardboard则导入Cardboard的SDK。这些SDK的使用方法大同小异,每个SDK中均包含着一个角色控制器,而对角色控制器的使用也近乎相同。我们将相应的SDK导入Unity,随后将SDK中的角色控制器拖放到游戏场景中,进行测试。在使用Oculus Rift等设备进行调试的时候,往往需要将Oculus Rift配置好,连接电脑才能调试。而Cardboard的调试,可以使用Alt键+拖动鼠标来模拟用户头部的晃动。
在正式开发游戏之前,采用一个良好的目录结构是项目管理的有效方式。这个项目中,在根目录下有如下的目录:Model(存放OBJ或是FBX格式的模型)、Texture(存放模型的贴图,PNG等格式的图片)、Material(存放通过贴图制作的Unity中的PBR贴图)、Prefab(存放Unity预设物体)、Scene(存放游戏的场景文件)。在这种目录结构下,我们还可以对Model、Texture、Prefab和Material等目录进行细分,在一些大的项目中拥有大量的模型的时候,通过建立Environment、Building和Player等目录以细化Model目录结构,以方便对于模型的寻找,加快开发速度。在对目录中的文件命名的时候,模型文件以M_模型名称进行命名,Material以Mat_贴图名称进行命名也不失为一种良好的习惯。
开发游戏的第一步便是搭建场景。在该VR游戏中,我们选用的风格是对程序员友好的像素3D风格。像素3D建模较为简单,所有的模型都是我们团队中的程序员制作的。在像素建模的软件选用方面,我们使用了Magica Voxel这款免费的软件。Magica Voxel的界面和操作十分简单,即使没有基础,跟着网上的教程半个小时左右就能入门,并做出自己心仪的3D模型。在建模阶段完成之后,将模型和材质等资源按照约定的目录结构导入Unity3D中。
在搭建场景时,先将FBX或是OBJ格式的模型拖动到Scene(场景)面板中,如果在建模的时候使用的单位和Unity默认单位(米)不同的话,便需要进行相应的缩放。通常如果是场景类的模型如Terrain(地形),我们选择将模型的Position属性设为(0,0,0),这样将会对后面的脚本编写和场景的搭建工作剩下时间。在简单地对模型进行拖动之后,得到了如下效果的游戏场景。
此时搭建好的场景是静态的,无法进行互动,我们需要进行相应脚本的编写,以实现游戏的可操控性。如下图所示,我们需要编写脚本的地方有3个,一个是蓝色的击球平台,一个是粉色的击球平台,一个是蓝色的球。
在这里,我们选择使用简单的AI来控制粉色的击球平台,玩家控制蓝色的击球平台。从这些物体我们可以引申出以下三个问题:
首先是如何移动玩家的击球平台。要解决这个问题,就需要确定一个输入方式。在VR游戏中有传统游戏中的使用手柄、键鼠输入,同时还有HTC Vive和Oculus Rift的动作捕捉。但我们决定使用的输入方式是Gaze Input(凝视输入)。凝视输入的原理是通过在角色控制器的摄像头射出一条射线,该射线代表玩家的视线,射线碰撞到的位置便是玩家目前凝视的位置。
在实现方面,需要在场景中新建一个Quad物体,与场景中的地面垂直,其宽度为玩家击球平台可以移动的范围,其高度可以设置为1000甚至更大。最后将该Quad的Mesh Renderer关闭,并调整其位置到玩家的击球平台的位置。然后,我们需要对VR中的SDK中的角色控制器进行相应的修改,由于该弹球游戏中采用的是固定视角,因此我们需要删除SDK中的角色控制器的RigidBody等组件,仅需要能跟随玩家头部运动的Camera即可。找到角色控制器中的Camera,在其上添加如下脚本RayCaster.cs:
float hitPos; void FixedUpdate() { Ray ray = new Ray(transform.position, transform.forward); RaycastHit hit; if (Physics.Raycast(transform.position, transform.forward, out hit)) { if (hit.collider.gameObject.tag == "Quad") { hitPos = hit.point.x; } } } public float getHisPos() { return hitPos; }
在上述脚本中,定义了一个射线和射线投影碰撞。当射线投影碰撞的对象是Quad的平面的时候获取碰撞点的x坐标(因只需移动弹球平台的X坐标,所以只获取碰撞点的X坐标),并保存到hitPos变量中,以便其他脚本调用。
接着在Hierarchy(阶层面板中)找到玩家控制的弹球平台,在其上编写脚本playerMovement.cs。
GameObject mainCamera; RayCaster rc; float thisX; void Start() { mainCamera = GameObject.FindGameObjectWithTag("MainCamera"); rc = mainCamera.GetComponent<RayCaster>(); thisX = this.transform.position.x; } void FixedUpdate() { this.transform.position=new Vector3(rc.getHisPos()+thisX,this.transform.position.y,this.transform.position.z); }
在上述脚本中,实现了通过获取MainCamera的RayCaster组件的碰撞点坐标来相应的移动弹球平台。
至此,通过视线来控制玩家击球平台的功能已经完成。对于电脑控制的击球平台,可以通过设定其平台的移动速度来决定难度,通过预测弹球到达电脑方的位置来决定电脑移动平台的目标点。在如何反弹弹球的问题上,我们使用Unity3D自带的物理引擎,在弹球物体上增加RigidBody组件,将RigidBody的Use Gravity选项取消选择,同时将Drag和Angular Drag设为0和Constraint中的Freeze Position的Y选项勾选上。这样,在游戏开始的时候,通过给弹球一个力来发球,当弹球碰到场景和击球平台的Collider的时候便会进行相应的反弹。至此,上面提出的三个问题解决完毕。
但以上三个问题都是显性的问题,解决完这三个问题后便可以对游戏进行简单的操作,并不能完成真正意义上的游戏。因为在游戏设计中,还有一些对象是隐性的,没有实际的物体形态。这些对象有Game Manager(游戏管理器)、State Machine(状态机)和User Interface(用户界面即UI)等。
在游戏管理方面,Game Manager下面有如下子Manager:Audio Manager(负责游戏中音效的管理)、Game Status Manager(负责游戏的阶段状态管理)、Score Manager(负责游戏计分的管理)和UI Manager(负责游戏UI的管理)等。以Game Status Manager为例,在不同的游戏阶段中,可以进行的动作将会不同。如在游戏开始之前的准备阶段和游戏结束阶段,弹球平台和弹球不可以移动。在游戏开始之前的准备阶段,需要对弹球和击球平台进行复位操作。通过Game Manager进行游戏管理来编写游戏,可以使程序更具有面向对象的特性,对于程序的修改、调试更为直观和方便,从而减少BUG出现的几率。
关于VR游戏中的UI,大部分Unity开发者在Unity4.6之后会倾向于选择官方的UGUI。在UGUI中,UI的TEXT、Button和Image等组件均是Canvas的子物体时才能正常工作。Canvas的默认渲染模式是以屏幕空间为基准的,然而在VR模式下,左右眼的视角均在一块屏幕中渲染,由此会造成UI在整块屏幕上只渲染一次而非分别在左右眼的视角分别渲染。因此,我们需要将Canvas的Render Mode(渲染模式)调整为World Space。这样,整块UI画布便成为了游戏3D世界中的物体,由此可缩放,拖动以放置到游戏中相应的位置。
至此,整个游戏制作完毕。但在发布游戏之前,还需要一些不可或缺的工作,如添加Image Effect视觉效果,对游戏进行配乐和进行游戏的测试等,以此来提升游戏的品质。
至于最后VR游戏的发布,现在市场上有不少与之相关的平台可供开发者选择。如:国外的Oculus Platform、PS VR和Steam VR,国内的Viveport、3Linker等。免费的,收费的,任君选择。
第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。
更多内容请关注VR知识库。该知识库包含了专家精心绘制的VR知识图谱,及由特邀编辑(领域专家)从海量数据中层层筛选出的精华内容和资源(学习视频、实践Demo、图书)。扫描下方二维码,立即查看VR知识库精彩内容。