嗨,大家好,我是新发。
昨天有同学私信我问我如何在Unity
中实现录屏的功能,
作为一个热心的博主,我今天就来实现这个功能吧,希望可以帮到这位同学~
首先思考一下,要实现录屏功能,我们需要先思考这两个问题:
1 如何获取屏幕图像信息?
2 这些屏幕图像如何采样并保存为可播放格式的文件呢?
2.1、问题一的解决方案
先回答第一个问题,如何获取屏幕图像信息?
最好先了解一下Unity
的渲染流程,我这里简单啰嗦几句。
我们游戏画面的最终的呈现是由CPU
与GPU
相互配合运算产生的效果,这个过程是一个流水线的模式,也称之为渲染流水线
,我们可将其分为三个阶段:应用程序阶段、几何阶段、光栅化阶段,画成图是这样子:
在最后一步屏幕图像
这里,Unity
提供了后处理回调接口给开发者:OnRenderImage回调
。
关于后处理我之前写了一篇演示的文章,感兴趣的同学可以看看:
Unity
会把当前渲染的图像存储在source
纹理中,我们可以使用Graphics.Blit
和特定的Shader
对当前图像进行处理,再把dest
显示在屏幕上。
Graphics.Blit
函数模型如下,它的功能就是使用着色器将源纹理复制到目标渲染纹理上。
如果不做任何后处理,其实就是直接把source
复制到dest
上,如下:
所以,这个source
或dest
就是我们要拿的屏幕图像了。
这样子拿到的rt
就是屏幕后备缓冲区的图像了,也就是我们屏幕显示的图像了。
2.2、问题二的解决方案
要把图像帧保存为可播放的格式的文件,我们比较常见的就是视频格式或者GIF
格式。如果是保存为视频格式(比如.avi
),需要用到OpenCV
库:OpenCVSharp
,可以在GitHub
上找到,
不过,因为我之前对GIF
有做过一点点研究,实现起来比较简单,所以我决定保存为GIF
格式,不使用OpenCV
。
在做录屏功能之前,我们得先有屏幕内容,嘛,那就找个妹子模型吧。
关于找资源,我之前写了一篇文章:,有了这些找资源的渠道,相信足够你平时学习使用了~
我找了下面这个妹子模型,喜欢的可以自行从Asset Store
上免费下载:。
不过光有模型不会动,这不行,我们要让她动起来~
给人物模型加动画,我给大家推荐一个宝藏网站Mixamo
:
Mixamo
是Adobe
旗下的一个产品,可以上传静态人形模型文件,在网站上绑定人形模板动画,并可以下载绑定动画后的模型文件,可以直接在Unity
中使用。
把.fbx
文件拖到如下框框中,
上传成功后,选择你喜欢的动作,
效果如下,这样子看好像有点吓人,
把FBX
文件导入到Unity
工程中,可以看到里面有一个动画文件,
把动画文件拖给我们的模型妹子,
生成的动画状态机如下:
此时我们播放动画会发现这个跳舞动画不会循环播放,我们需要设置一下循环播放,选中动画文件,
重新播放动画,可以循环播放了,如下:
可以多试几个舞蹈动作,
到了写代码的环节了,不过写代码之前,我们先设计一下程序模块,如下:
我们先从Recorder
模块写起,先定义我们需要的成员变量,
用协程实现屏幕图像采样,
上面RenderTexture.GetTemporary
是获取临时渲染纹理,因为每次使用的纹理尺寸是一样的,我们不需要每次重复构建纹理对象,可以利用Unity
提供给我们的临时渲染纹理来重复使用,这样可以提升性能。
开始录制和停止录制就是开启协程和停止协程,
先定义下针对列缓存的成员,最关键的就是队列变量StoredFrames
,
实现塞入帧数据的接口,如下:
其中,GifFrame
为帧数据结构,如下:
生成GIF
需要一些运算时间,为了不卡住主线程,我们使用Thread
线程来处理。
核心的运算模块是GifEncoder
,我们通过它来编码生成GIF
文件,
这个GIF
编码器GifEncoder
就是按照GIF
的编码格式进行写入即可。
所以要给头部写入对应的字节:
补充一下其他二进制格式的头部标识:
再封装一个结束的方法,把GIF
的结束标识0x3b
写入文件末尾,
制作下简单的UI
,如下:
给主摄像机添加Recorder
组件,设置好参数,
最后运行Unity
,效果如下:
看下生成GIF
耗时488
毫秒,
生成的GIF
文件保存在GifOutput
文件夹中:
本工程源码已上传到CodeChina
,感兴趣的同学可自行下载学习。
好了,今天就写到这里吧,如果有什么技术上的问题,欢迎留言或私信,我是新发,拜拜~