Unity3D OpenVR 虚拟现实 保龄球打砖块游戏开发

2023-11-06 00:32

本文主要是介绍Unity3D OpenVR 虚拟现实 保龄球打砖块游戏开发,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

据说水哥买了 Valve Index 设备,既然这个设备这么贵,不开发点有(zhi)趣(zhang)游戏就感觉对不起这个设备。本文将来开始着手开发一个可玩性不大,观赏性极强的保龄球打砖块游戏。这仅仅只是一个入门级的游戏,代码量和制作步骤都超级少,适合入门

在开始之前,请参阅水哥提供的环境搭建以及部分必备知识博客

  • Unity OpenVR 虚拟现实入门一:安装配置 Unity + OpenVR 环境

  • Unity OpenVR 虚拟现实入门二:一个最简单的虚拟现实游戏/程序

在阅读本文之前,我期望你有部分 Unity3D 开发的知识,本文不会提及多少 Unity3D 入门的知识,如果有看不懂的地方,还请自行翻 Unity3D 入门知识

此游戏的玩法就是用双手拿起保龄球,将一堵墙砸掉,将砖块推下地板。效果视频如下

写代码就和搬砖一样,一开始咱先使用 Unity OpenVR 虚拟现实入门二:一个最简单的虚拟现实游戏/程序 的方法搭建出来一个放在 SteamVR SDK 里面的 Sample 的内容,开始进行砌墙

以上墙里面的各个砖块记得加上刚体(Rigidbody)同时设置质量为 0.2 不然咱可打不掉砖块

接下来咱来创建保龄球子弹,按照约定创建 Prefabs 文件夹,在里面创建一个叫 Bullet 的圆球

如上图,同样给此子弹加上刚体,设置比较大的质量。如上图给了质量是 10 这样才好将砖块打到地板下。请不要将地板加上刚体哦,默认的刚体是加上重力的,刚进入调试发现地板掉了,这可不是在做恐怖游戏哈

下面咱来写一点代码,用来在扣扳机的时候,创建保龄球子弹

如何在 SteamVR 游戏中,获取当前扳机的状态?其实按照 Unity3D OpenVR SteamVR Input Action 动作 博客的建议,咱是不开发获取当前扳机状态的代码。咱需要开发的是定义某个动作,如 InteracetUI 这个动作,获取此动作的值来决定逻辑。这样做的好处是方便用户进行配置,以及支持其他不同的交互设备。如某个设备没有扳机,但是此设备有另一个按钮,这个按钮也可以实现此效果,那么就可以让用户绑定新的按键

咱现在还在 VR 应用或游戏开发的蛮荒时代,很多交互都在摸索阶段,为了更好适配未来的新硬件和交互,通过定义动作名而不是绑定具体的硬件设备上的做法的适配性更强

咱来创建一个叫 ShootWithRotation 的 C# 脚本文件,按照国际惯例,放在 Scripts 文件夹里面

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Valve.VR;
using Valve.VR.InteractionSystem;public class PlayerDemoScript : MonoBehaviour
{// Start is called before the first frame updatevoid Start(){}// Update is called once per framevoid Update(){}
}

咱添加一个字段,按照 Unity3D OpenVR SteamVR Input Action 动作 博客的内容,咱需要一个 bool 值获取当前的扳机是否按下。在 SteamVR 里面,布尔使用 SteamVR_Action_Boolean 类型表示,通过 state 属性获取值,代码如下

public SteamVR_Action_Boolean Shooting;

获取扳机是否按下的代码如下

            if (Shooting.state){Shoot();}

通过 state 即可获取当前的扳机是否按下,以上代码的 Shoot 方法就是实际的射击代码,这部分代码咱在下文才写。回到 Shooting 字段的定义。因为我主业是 WPF 开发,按照我的编码习惯,字段是不会公开的,而且使用下划线开头,但这和 Unity3D 这边的编码规范冲突,于是我就将字段当成属性好了,第一个字符大写

咱上面代码定义的 Shooting 字段,想要获取交互的本身就需要在 Unity3D 里面进行绑定交互,此绑定交互的方法可参阅 Unity OpenVR 虚拟现实入门六:通过摇杆控制玩家移动 这一篇的内容。大概的做法就是先将脚本附加到某个游戏对象里面。如咱将这个脚本附加到 Player 对象上面,接下来点击 Shooting 的下拉,选择交互

咱选择 InteracetUI 这个动作,默认在 SteamVR 里面就是扣扳机这个交互,当然,用户也可以自己设置到其他按键里面

此时我推荐大家如果之前没有做过 SteamVR 的交互,那请尝试在 VisualStudio 里面附加 Unity3D 调试,在 Update 方法里面获取 Shooting 字段的值了解这部分的交互

如上图,此时咱将 Shooting 字段和 InteracetUI 这个动作绑定

上图里面的 Bullet 字段以及 Shoot Speed 字段等,咱将进行定义,代码如下

    public GameObject Bullet;public SteamVR_Action_Boolean Shooting;public float Speed = 5;public float ShootSpeed = 2;

以上代码的 Bullet 就是保龄球子弹的模版,用来创建保龄球子弹,而 ShootSpeed 是射击频率。在 VR 应用中,如果在 Update 里面不通过判断频率,就进行创建子弹,那么将会因为超级高的刷新而让子弹创建速度超级快。本文这里的代码判断频率只是用了直观快速的方法

通过下面代码可以用来限制发送子弹的速度

    public GameObject Bullet;public SteamVR_Action_Boolean Shooting;public float Speed = 5;public float ShootSpeed = 2;private float _shootTime = 0;private float _shootTimerInterval = 0;void Start(){_shootTimerInterval = 1 / ShootSpeed;}void Update(){_shootTime += Time.deltaTime;if(_shootTime> _shootTimerInterval){_shootTime -= _shootTimerInterval;if (Shooting.state){Shoot();}}}

下面就是 Shoot 代码的编写了,我编写了几个版本,经过了水哥的测试,也就是本文如下没有注释掉代码的版本的交互是最好的(虽然可玩性也特别渣)因此咱下面将来写这个版本的逻辑

通过 GameObject.Instantiate 方法创建子弹,接着将子弹放在旁边即可

    private void Shoot(){var sphere = GameObject.Instantiate(Bullet);sphere.transform.Translate(new Vector3(0, 0.25f, 0.1f));}

因为咱的 Player 和地板没有添加传送的功能,因此在设置 Player 在原点时,刚好将子弹放在 (0,0.25,0.1) 的地方即可。为什么 y 是 0.25 是因为刚好球大小就是 0.5 而坐标中点是球心,通过球的一半即可刚好放在地板上。而 z 方向设置 0.1 是可以让球刚好在前面

此时在 Unity 绑定 Bullet 字段到咱上文设置的 Prefbabs 里面的 Bullet 即可,跑起来,通过刚体的逻辑,可以使用双手拿起球,开始玩起来

接下来是一个被干掉的交互方式,此交互方式是扣扳机进行射击,射击方向就是前方

实现方式是在创建子弹时,将子弹的旋转设置和当前 HMD (头戴式显示器 Head-mounted display)的方向相同,然后设置速度方向为物体前方,代码如下

    private void Shoot(){var sphere = GameObject.Instantiate(Bullet);sphere.transform.Translate(new Vector3(0, 0.25f, 0.1f));// 向着用户看到方向sphere.transform.rotation = Player.instance.hmdTransform.transform.rotation;var rigidbody = sphere.GetComponent<rigidbody>();rigidbody.velocity = sphere.transform.forward * Speed;}

以下是 ShootWithRotation 的全部代码

using System;
using System.Collections;
using System.Collections.Generic;using UnityEngine;using Valve.VR;
using Valve.VR.InteractionSystem;public class ShootWithRotation : MonoBehaviour
{public GameObject Bullet;public SteamVR_Action_Boolean Shooting;public float Speed = 5;public float ShootSpeed = 2;private float _shootTime = 0;private float _shootTimerInterval = 0;// Start is called before the first frame updatevoid Start(){_shootTimerInterval = 1 / ShootSpeed;}// Update is called once per framevoid Update(){_shootTime += Time.deltaTime;if(_shootTime&gt; _shootTimerInterval){_shootTime -= _shootTimerInterval;if (Shooting.state){Shoot();}}}private void Shoot(){var sphere = GameObject.Instantiate(Bullet);//sphere.transform.Translate(Player.instance.hmdTransform.position);sphere.transform.Translate(new Vector3(0, 0.25f, 0.1f));// 向着用户看到方向sphere.transform.rotation = Player.instance.hmdTransform.transform.rotation;var rigidbody = sphere.GetComponent<rigidbody>();//rigidbody.velocity = sphere.transform.forward * Speed;旋转发射//var rotation = Player.transform.eulerAngles.y;//var vx = 1 * Mathf.Cos(rotation);//var vy = -1 * Mathf.Sin(rotation);//rigidbody.velocity = new Vector3(vx, 0, vy) * Speed;//Destroy(sphere, 5);}
}

当前后续水哥还开发出通过抓握的交互方式,这个交互方式看起来更好玩。实现方法是给子弹加上一个叫 Interactable 的脚本,这个脚本是带在 SteamVR SDK 里面的。添加这个脚本时需要给定他的 activateActionSetOnAttach 字段 \actions\default 交互

再给子弹添加一个 Throwable 脚本,让这个球可以被扔掉

当前的游戏就可以抓起来球然后扔出去

这个游戏开发难度不高,只是有很多知识需要了解,而且有点费德熙。我在调试了几个小时,看着屏幕上工具人水哥测试的画面,特别想吐

系列博客请看

  • Unity OpenVR 虚拟现实入门一:安装配置 Unity + OpenVR 环境

  • Unity OpenVR 虚拟现实入门二:一个最简单的虚拟现实游戏/程序

  • Unity OpenVR 虚拟现实入门三:最简单的五指交互

  • Unity OpenVR 虚拟现实入门四:通过脚本控制手与控制器

  • Unity OpenVR 虚拟现实入门五:通过传送控制玩家移动

  • Unity OpenVR 虚拟现实入门六:通过摇杆控制玩家移动

这篇关于Unity3D OpenVR 虚拟现实 保龄球打砖块游戏开发的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/353446

相关文章

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

Python基于wxPython和FFmpeg开发一个视频标签工具

《Python基于wxPython和FFmpeg开发一个视频标签工具》在当今数字媒体时代,视频内容的管理和标记变得越来越重要,无论是研究人员需要对实验视频进行时间点标记,还是个人用户希望对家庭视频进行... 目录引言1. 应用概述2. 技术栈分析2.1 核心库和模块2.2 wxpython作为GUI选择的优

利用Python开发Markdown表格结构转换为Excel工具

《利用Python开发Markdown表格结构转换为Excel工具》在数据管理和文档编写过程中,我们经常使用Markdown来记录表格数据,但它没有Excel使用方便,所以本文将使用Python编写一... 目录1.完整代码2. 项目概述3. 代码解析3.1 依赖库3.2 GUI 设计3.3 解析 Mark

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

基于Python开发批量提取Excel图片的小工具

《基于Python开发批量提取Excel图片的小工具》这篇文章主要为大家详细介绍了如何使用Python中的openpyxl库开发一个小工具,可以实现批量提取Excel图片,有需要的小伙伴可以参考一下... 目前有一个需求,就是批量读取当前目录下所有文件夹里的Excel文件,去获取出Excel文件中的图片,并

基于Python开发PDF转PNG的可视化工具

《基于Python开发PDF转PNG的可视化工具》在数字文档处理领域,PDF到图像格式的转换是常见需求,本文介绍如何利用Python的PyMuPDF库和Tkinter框架开发一个带图形界面的PDF转P... 目录一、引言二、功能特性三、技术架构1. 技术栈组成2. 系统架构javascript设计3.效果图

基于Python开发PDF转Doc格式小程序

《基于Python开发PDF转Doc格式小程序》这篇文章主要为大家详细介绍了如何基于Python开发PDF转Doc格式小程序,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 用python实现PDF转Doc格式小程序以下是一个使用Python实现PDF转DOC格式的GUI程序,采用T

使用Python开发一个图像标注与OCR识别工具

《使用Python开发一个图像标注与OCR识别工具》:本文主要介绍一个使用Python开发的工具,允许用户在图像上进行矩形标注,使用OCR对标注区域进行文本识别,并将结果保存为Excel文件,感兴... 目录项目简介1. 图像加载与显示2. 矩形标注3. OCR识别4. 标注的保存与加载5. 裁剪与重置图像