关于Unity的截屏方法

作者: magicbell | 来源:发表于2016-11-07 19:59 被阅读734次

序:开始决定写东西,内容不限,关于工作内容的,关于自己业余研究的,关于生活的...因为只有写下来,思路才会更清晰,印象才会更深刻,更可以Share。ps:我是个女码农,现在从事Unity游戏、应用的开发。不要试图问一个女生为什么选择这个职业,做了就是做了,并且要做好。


Ok,well这次简短点,我最近碰到一个关于Unity截屏的问题。用过的人很快会想到两种截屏的方式:

  1. Application.CaptureScreenshot(string file name),这会截取当前屏幕保存为png格式,存放在Application.dataPath(PC/Mac),Application.persistantDataPath(移动设备)。如果需要获取图片用作显示,或保存在系统照片集下,就需要通过www的方式读取后再做处理,不是很方便。

  2. Texture2D.ReadPixels(Rect source, int destX, int destY, bool recaculateMipmaps=true), 这会读取指定区域内的屏幕像素至一张texture中,用于UI显示、保存等。相比方法一更方便直观。我们大多数都是采用该方法。

但是,最近碰到的问题是,在一些低端性能差点的Android设备上,用以上两种方式截出来的图是黑色(像素值全是0),用了coroutine方式WaitEndOfFrame,试图修改Texture2D的format、size,放在Monobehavior.OnPostRender()中...试过想到的各种方法均无效,也没有报warning、error。就想到尝试用第三种方式来实现:RenderTexture。

通过将Camera的内容渲染到一张RT中,然后用Texture2D.ReadPixels()方法从当前的RT中读取,结果可行!代码如下:

public static Texture2D CaptureCamera(Rect rect,  params Camera[] cameras)
{
    RenderTexture rt = new RenderTexture ((int)Screen.width, (int)Screen.height, 24);
    //临时设置相关相机的targetTexture为rt, 并手动渲染相关相机
    for (int i=0; i<cameras.Length; i++)
    {
        if(cameras[i] != null)
        {
            cameras[i].targetTexture=rt;
            cameras[i].Render();
        }
    }

   //激活这个rt, 并从中中读取像素。
   RenderTexture.active = rt;
   Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);
   screenShot.ReadPixels(rect, 0, 0);   //注:这个时候,它是从RenderTexture.active中读取像素
   screenShot.Apply();
   
   //重置相关参数,以使用camera继续在屏幕上显示
   for(int i=0; i<cameras.Length; i++)
   {
       if(cameras[i] !=null)
          cameras[i].targetTexture = null;
   }
            
   RenderTexture.active = null;
   GameObject.Destroy(rt);

   return screenShot;
}

分析原因,有如下推断:Android渲染采用了双缓冲,而前两种方式是从绘制到当前屏幕的framebuffer中读数据,当设备运行慢时,在Unity调用接口所读到的数据是从正在写入的framebuffer里面的,还没有swap送入屏幕显示,所以读到的像素值为0。采用RenderTexture方式将Camera绘制内容写入texture中,从该texture中读取数据能够解决上述问题,确保数据有效。
这是我的一个推断,可能是其他原因,搜索以及debug无果,希望以后的开发中能彻底知晓原因。

相关文章

  • 关于Unity的截屏方法

    序:开始决定写东西,内容不限,关于工作内容的,关于自己业余研究的,关于生活的...因为只有写下来,思路才会更清晰,...

  • Unity功能记录(一) ------ 截图/录屏保存到相册(A

    截屏和录屏unity端代码都已经分享过 :Unity功能记录(十七) ------ 截屏功能Unity插件(二) ...

  • Unity截屏

    屏幕截图时需要在协程中执行,且必须有yield return new WaitForEndOfFrame();,否...

  • iOS-百度地图截屏

    关于百度地图截屏的问题,发现不能用常用的方法进行载屏,常用的截屏方法所得到的图片地图瓦片底图会显示空白,网上给出的...

  • Unity编辑器录屏神器:Unity Recorder

    摘要:汇报工作进展时你还在使用截屏或者录屏软件?来试试Unity Recorder插件,一站解决截屏、录屏、全景图...

  • unity ios 截屏

    最近项目需要ios响应的截屏功能,参考网上一些资料,code如下 需要注意的是:IOS的XCODE打包要选择打开相...

  • Unity 截屏功能

    原文链接 https://zhuanlan.zhihu.com/p/102158263 使用方法 1、选择相机 2...

  • Unity踩坑日志:关于unity与iOS交互的坑

    在原生中调用unity导出的iOS工程 1.一个需求是进行截屏,同时隐藏UI,截屏之后显示UI,并显示“已保存至系...

  • 在Mac上获取截屏的方法

    mac上截屏有很多种方法,下面介绍几种常用的,可以从中选择更适合的方法截屏,以使获得的截屏更符合要求与审美。 1、...

  • 截屏方法

    (UIImage *)captureScreen{UIWindow *keyWindow = [[UIApplic...

网友评论

    本文标题:关于Unity的截屏方法

    本文链接:https://www.haomeiwen.com/subject/tjhouttx.html