初步学习了Unity后,觉得上手很快,也很好玩。
然后最近生日,媳妇给送了一个Oculus Quest2,是Facebook搞的VR眼镜,而恰好Unity对VR和AR的支持比较早,基于它去学VR游戏开发,应该不难。
所以我想着边学边做,看能不能搞出个VR游戏来,最后真做出来了,是一个结合TensorFlowLite、Unity、Oculus SDK以及Google开源手绘数据集做的游戏,玩法很简单,AI出题,玩家画,画的像就过关(你画我猜的玩法),视频演示如下:
过关会随机放不同款式烟花。
接下来,简单谈谈这次学习的历程。
在学习和开发这个VR游戏之前,我稍微了解了一下目前VR市场的规模情况。
根据IDC《全球AR/VR头显市场季度跟踪报告,2021年第四季度》,2021年全年全球AR/VR头显出货量达1,123万台,同比增长92.1%,其中VR头显出货量达1,095万台,突破年出货量一千万台的行业重要拐点,其中Oculus份额达到80%。预计2022年,全球VR头显出货1,573万台,同比增长43.6%。硬件覆盖方面,貌似是存在较好的势头的。
而根据Facebook今年2月公布的数据,在Quest平台超过60款游戏收入超过100万美元,6款游戏收入超过1000万美元。如《Beat Saber》(节奏空间)已售出400万份,营收或超1.8亿美元。《Onward》上线Quest平台仅4天收入就超过100万美元。
对于软体方面,VR游戏目前好像没有内购和广告的变现方式,大部分游戏是靠把游戏放在平台上卖来变现的,目前应该还处于蓝海,看着也有一定机会。
当然谈到VR,可能就会谈到元宇宙(当然元宇宙不等于VR),最近朋友圈里有一篇文章还是挺火的。
最近关于元宇宙最理性的分析 爱游戏的葡萄君,公众号:游戏葡萄腾讯马晓轶分享:为什么说要到2030年才能实现元宇宙?
其实2030年离现在也就8年,好像也并不是太遥远,而元宇宙的知识体系比VR要庞大得多,VR作为虚拟世界的重要入口,在元宇宙实现前,肯定也要先发展起来。
那么现在开始学,也许还能跟上时代步伐。
好了,有依据了,就开始动手学。
这次没有像之前学习Unity基础知识那样对整个学习过程进行理性统筹,这次还是比较随意的,也是熬夜搞搞,但也遵循2个重点步骤:
1.简略的游戏策划
画画类游戏研发量不大却能吸引用户,比较适合我用零碎的业余时间进行创作,所以大基调就是做画线相关的游戏。以前做过类似的画画游戏,随手画个简单的交互如图:
2.详细的可行性评估
这个游戏最难的技术难题是:搞定AI模型对手绘图识别。虽然我以前在web平台实现过类似的逻辑,但在Unity上实现还是有一定的迁移难度。这需要拆分成4个点来攻破:
- Unity中实现画线
- Unity中实现tensorflow的使用
- Unity中正确截图和裁图,用于转化为正确的、格式化的输入数据
- VR视觉和交互(如聚焦、点击)的实现
对于第1点,Unity中实现画线
只要稍微研究下,就会发现Unity中有一个叫LineRender的Component,这个Component封装了很方便的线条生成方法,里面包含了转折平滑、线条渐细等一系列功能,用起来很简单,这里就不细说了。
对于第2点,Unity中实现tensorflow的使用
复习一下AI识别图形的技术流程:
数据集制作->用数据集训练出模型->用Tensorflow读取模型->格式化输入数据->AI判断相似度
关于在Unity中实现TensorFlow的使用,其实Github上面有个大神基于TensorFlowLite封装了一个库。
https://github.com/asus4/tf-lite-unity-sample
里面会有各种结合Unity的AI Demo,但对于手绘的只有一个画数字的demo,里面有一个手绘数字的模型,但显然对于我这个游戏来说是不够用的,我需要做一个lite版的手绘集模型,而且我不可能自己去生产数据集,于是Google的手绘开源数据集就派上用场了。
https://github.com/googlecreativelab/quickdraw-dataset
我以前就用过这个数据集,生成模型的逻辑很简单:使用 Keras 框架在Google Colab 免费提供的 GPU 上训练模型。
https://colab.research.google.com/github/zaidalyafeai/zaidalyafeai.github.io/blob/master/sketcher/Sketcher.ipynb
但有个问题是这个脚本生成的是keras模型,我们要在TensorFlowLite里用的话,还得把它转成lite版的模型。方法其实也不难,就是转换一下:
import tensorflow as tfmodel.save('model.h5')tflite_model = tf.keras.models.load_model('model.h5')converter = tf.lite.TFLiteConverter.from_keras_model(tflite_model)tflite_model = converter.convert()with open('model.tflite', 'wb') as f:f.write(tflite_model)from google.colab import filesfiles.download('model.tflite')
这样模型文件就能准备好了,接着就是准备格式化的输入数据。
对于第3点,Unity中正确截图和裁图,用于转化为正确的、格式化的输入数据
说实话,这一点虽然逻辑很简单,但反倒是卡了我好久,逻辑是:
Unity中用Camera捕获帧的texture图片纹理数据,然后对图片进行周边留空裁剪,之后按1:1比例做居中,最后按模型要求的28宽和高缩放图片纹理,最终传给tensorflow进行分析。
然后这个逻辑存在一个性能优化点,如果直接在c脚本中去裁剪和缩放图片,那种像素级处理的逻辑是发生在cpu上的,性能一定会有问题。
为了解决这个问题,我们需要借助GPU,这就涉及到在Unity中怎么用ComputerShader的问题了。Unity中调起GPU实行图形运算的方法:编写HLSL语法的xx.compute文件,挂载并传参(可以是可读写的texture或buffer),然后多进程运算更改传参。
常规脚本中:
裁剪四周留白的HLSL文件部分代码(目的是把算出来的最左、最右、最下、最上四个坐标点的标识传给buffer):
然后看着逻辑是对的,在Mac下面调试器运行也是对的,但放在VR眼镜中就会出现偶发失败(至今没找到原因),但多次运算后还是能成功。
这样数据能格式化并传给tensorflow后,AI流程就算跑通了。
对于第4点,VR视觉和交互(如聚焦、点击)的实现
对于视觉,我直接用Unity默认的URP模型,这种模式下,元素可以很容易实现发光效果,元素在氛围衬托下,没太多的设计细究也不会太难看。
而对于交互,比起传统UI交互,VR的交互是一种射线的交互,意思是通过双手位置发起射线,途经的地方会发生交互,同时控制器上按钮的事件对射线落地点的物体起作用。
unity内置的XR已经兼容oculus,交互方式分两种:
- UI交互
- 在renderMode为worldSpace的canvas上挂载: TrackedDeviceGraphicRaycaster;
- 在eventSystem上挂载XR UI Input Module;
- 在对应的XR Controller(比如手柄)的物体上挂载XR Ray Interactor ;
- UnityEngine.XR.InputDevices全局类,可通过:
获取设备,然后通过以下方式获取对应按钮信息(https://docs.unity3d.com/ScriptReference/XR.InputDevice.html)
OnPrimary2DAxis为
对应方法体为:
- 3d交互
- 在拥有collider的物体上挂载XR Simple Interactable
- 在对应的XR Controller(比如手柄)的物体上挂载XR Ray Interactor ,定义事件:
相关usingUnityEngine.XR.Interaction.Toolkit;
这几个步骤攻克后,配合交互稿进行研发和调优,游戏就能很快做出来了,接下来试着看看能不能发布到Oculus平台上。
好了,先讲到这里,有兴趣一起学的可以留言交流哈。