一个需求

我需要在场景中截取不同层级的截图(如只截模型或只截UI或只截外部相加看到的画面 或全都截或和Shader配合呈现人眼夜视仪热成像的画面切换)
将截图排到列表中,在场景UI中展示出来

如何做

  1. 相机要能够看到不同的画面
  2. 将当前帧画面存储下来
  3. 将存储的画面展示出来

实现时需要掌握的知识点

相机要能够看到不同的画面
  1. 将不同的游戏对象分类成不同的Layer
  2. 需要单独设置一个相机x与原相机保持一致,唯独更改它的Rendering->CullingMask 规定它可以看什么不看什么,还有Rendering->Priority层级要高于原相机 (还要关闭它的AudioListener,防止重复)
  3. 通常我们要关掉,只在截图的时候打开它
动态控制摄像机Rendering->CullingMask的方法
public Camera cameraToChange; //控制的相机 public LayerMask newCullingLayers; //选择Layers void SetCullingMask() { //显示选择的Layers cameraToChange.cullingMask = newCullingLayers; } void ToggleCullingMask() { // 取反剔除层 cameraToChange.cullingMask = ~cameraToChange.cullingMask; } void DisableAllLayers() { //全部剔除 cameraToChange.cullingMask = 0; }
将画面存储下来
需要输入宽度和高度用于创建Texture2D和截图内容用,有两种方式意思直接输入屏幕存储或创建一个image,常用这个image宽高
int width = Screen.width; int height = Screen.height;public RectTransform UIRect; { //计算截图的宽度和高度 int width = (int)(UIRect.rect.width); int height = (int)(UIRect.rect.height); //创建一个新的Texture2D对象,宽度和高度与截图的宽度和高度匹配 Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false); }
储存方法
事先要创建出StreamingAssets文件夹
public RectTransform UIRect; public RawImage rawImage; // 添加一个RawImage对象 void Update() { if (Input.GetKeyDown(KeyCode.Q)) { string fileName = Application.dataPath + "/StreamingAssets/" + "12.png"; //系统不识别标点符号,但支持中文 IEnumerator coroutine = CaptureByUI(UIRect, fileName); StartCoroutine(coroutine); } } public IEnumerator CaptureByUI(RectTransform UIRect, string mFileName) { yield return new WaitForEndOfFrame(); //等待当前帧的UI渲染完成 //计算截图的宽度和高度 int width = (int)(UIRect.rect.width); int height = (int)(UIRect.rect.height); //创建一个新的Texture2D对象,宽度和高度与截图的宽度和高度匹配 Texture2D tex = new Texture2D(width, height, TextureFormat.RGB24, false); //计算从屏幕上读取像素的起始位置 float leftBtmX = UIRect.transform.position.x + UIRect.rect.xMin; float leftBtmY = UIRect.transform.position.y + UIRect.rect.yMin; //使用tex.ReadPixels()函数从屏幕上读取指定区域的像素,并存储到Texture2D中。 tex.ReadPixels(new Rect(leftBtmX, leftBtmY, width, height), 0, 0); //执行读取操作,将修改应用到Texture2D中 tex.Apply(); //将Texture2D编码为PNG格式的字节数组 byte[] bytes = tex.EncodeToPNG(); //将字节数组保存为PNG图片文件 System.IO.File.WriteAllBytes(mFileName, bytes); }
将存储的画面展示出来
到UnityWebRequest 从给的路径里拿数据
public RawImage rawImage; public string imageFileName; void Update() { if (Input.GetKeyDown(KeyCode.W)) { // 拼接图片路径 string imagePath = System.IO.Path.Combine(Application.streamingAssetsPath, imageFileName); // 开始协程加载图片 StartCoroutine(LoadImage(imagePath)); } } IEnumerator LoadImage(string path) { // 发送请求获取图片 UnityWebRequest www = UnityWebRequestTexture.GetTexture(path); yield return www.SendWebRequest(); // 检查请求是否成功 if (www.result == UnityWebRequest.Result.Success) { // 获取加载的Texture Texture2D texture = DownloadHandlerTexture.GetContent(www); // 将加载的Texture赋值给RawImage的texture属性 rawImage.texture = texture; // 调整RawImage的大小以适应图片的长宽比例 rawImage.SetNativeSize(); } else { Debug.LogError("Failed to load image: " + www.error); } }
Logo

分享前沿Unity技术干货和开发经验,精彩的Unity活动和社区相关信息

更多推荐