林先生。 发表于 2022-11-18 10:36:58

使用Unity3D开发一款VR弹球游戏

开发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等。免费的,收费的,任君选择。


VR开发还在路上,我们共同进步。欢迎投稿至tumin@csdn.net,分享你的VR应用开发或内容创作经验与心得。



更多内容请关注VR知识库。该知识库包含了专家精心绘制的VR知识图谱,及由特邀编辑(领域专家)从海量数据中层层筛选出的精华内容和资源(学习视频、实践Demo、图书)。扫描下方二维码,立即查看VR知识库精彩内容。

页: [1]
查看完整版本: 使用Unity3D开发一款VR弹球游戏