Tips:这里就是用HTC Vive头盔下来做为例子。
这个可以参考官方给的例子和代码 https://docs.unity3d.com/ScriptReference/Application.CaptureScreenshot.html
1. void OnMouseDown() { 2. Application.CaptureScreenshot("Screenshot.png"); 3. }
这个是使用相机来渲染画面,根据相机的画面来保持纹理,把纹理保存为图片。
1. void LateUpdate() 2. { 3. 4. if (Input.GetKeyDown("s")) 5. { 6. StartCoroutine(SaveCameraView()); 7. } 8. 9. }
所以也有屏幕读取数据的局限
1. Texture2D tex = new Texture2D(Screen.width, Screen.height); 2. tex.ReadPixels(new Rect(0,0,Screen.width,Screen.height),0,0); 3. tex.Apply();
1. VR中特位置截图
对于截取VR中,若截取全屏使用上面的任意方法都可以。
但是VR的特点就是相机有玩家来控制,不知道玩家相机的朝向和位置。这个就需要固定位置的截图。
某个固定位置对象来说,只能使用RenderTexture来实现。
这个里面有两个问题。
第一,VR相机的旋转是灵活的,且在vive中,硬件头盔会控制所有相机的旋转。
第二,就是不能使用于屏幕相关的参数,因为屏幕大小在不一定。
这里的问题,我们就逐一来解决和说明。
2.实现代码
首先,创建一个RenderTexture,这个做为public,有外面拖拽,在外面定义的RenderTexture来创建好大小和格式。这样容易控制图片大小和格式,策划容易修改。
其次,解决VR相机能控制所有相机的问题,不能在特定位置预先放置相机,然后在某时刻获取RenderTexture,虽然也可成功截图,但是可能由于相机的角度不停在改变,造成截图移位或倾斜。
在代码中实时的创建相机。
代码如下:
1. private IEnumerator CaptureByRect(string mFileName) 2. { 3. //等待渲染线程结束 4. yield return new WaitForEndOfFrame(); 5. // 实时来创建相机,硬件相机来不及绑定,不会造成偏移和旋转。 6. GameObject gob = new GameObject(); 7. gob.transform.position=CameraTrans[0].transform.position; 8. gob.AddComponent(); 9. Camera mCamera =gob.GetComponent(); 10. // 相机投影为正射投影,防止变形和策划调整难度大。 11. mCamera.orthographic = true; 12. mCamera.farClipPlane= 20; 13. mCamera.orthographicSize= 5f; 14. mCamera.transform.rotation= new Quaternion(0, 0, 0, 0); 15. //mCamera.cullingMask= 1 << 5; 16. mCamera.targetTexture= shotTexture; 17. 18. // get the camera'srender texture 19. RenderTexture.active= mCamera.targetTexture; 20. 21. // render thetexture 22. mCamera.Render(); 23. int height =mCamera.targetTexture.height; 24. Texture2DcameraImage = new Texture2D(55, 57, TextureFormat.RGB24, false); 25. cameraImage.ReadPixels(new Rect(100, 105, 55, 57), 0, 0); 26. cameraImage.Apply(); 27. // store the textureinto a .PNG file 28. byte[] bytes =cameraImage.EncodeToPNG(); 29. System.IO.File.WriteAllBytes(mFileName,bytes); 30. Destroy(gob); 31. //等待渲染线程结束 32. yield return new WaitForEndOfFrame(); 33. AssetDatabase.Refresh(); 34. }
这里面使用RenderTexture大小为256*256的,根据截图大小来确定Texture读取像素位置。
这里的代码注释写的还算详细,也容易看懂就不多说了。
3. 关于改进
关于保存图片,这个在使用有卡顿现象。
试图使用线程来解决,但是策划说效果不明显,还不如不使用。
1. new System.Threading.Thread(() => 2. { 3. System.Threading.Thread.Sleep(100); 4. System.IO.File.WriteAllBytes(mFileName, bytes); 5. 6. }).Start();