unity 自由框选截图(两种方法,亲测有效)
提示:文章有错误的地方,还望诸位大神不吝指教!
文章目录
- 前言
- 一、第一种方法
- (1)简介GL
- (2) GL 用法:
- (3)具体代码
- 二、第二种方法
- 第一步:
- 第二步
- 第三步 代码
- 总结
前言
unity版本2019.3.7f1
本文提供两种截图方式,都是亲测可用。
第一种使用GL画线来实现
第二种使用Image来实现
总的逻辑都是一样的。
下面是两种方式的效果图:



提示:以下是本篇文章正文内容,下面案例可供参考
一、第一种方法
使用GL来画一个框,作为截图区域。
(1)简介GL
Graphics Library(简称 GL),包含一系列类似 OpenGL 的 Immediate 模式的渲染指令,比 Graphic.DrawMesh() 更高效。GL 是立即执行的,如果在Update() 方法里调用,它们将在相机渲染前执行,相机渲染前会清空屏幕,GL 渲染效果将无法看到。
(2) GL 用法:
在相机上挂脚本,并在 OnPostRender() 方法里执行(MonoBehaviour的生命周期)。GL 渲染的图像不需要 GameObject 承载,在 Hierarchy 窗口不会生成 GameObject 对象。
另外需要给一个Material 作为材质
(3)具体代码
记得挂载在相机上,并且给一个Material 。
/**********************************************************************文件信息文件名(File Name): SelectScreenshot.cs作者(Author): 野区捕龙为宠创建时间(CreateTime): #CREATETIME#**********************************************************************/
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System;
using System.IO;namespace Twq
{public class SelectScreenshot : MonoBehaviour{private Color rColor = Color.green;private Vector3 start = Vector3.zero;private Vector3 end = Vector3.zero;public Material rMat;private bool drawFlag = false;private Rect rect;private Texture2D cutImage;// Use this for initialization void Start(){}// Update is called once per frame void Update(){if (Input.GetMouseButtonDown(0)){drawFlag = true;//如果鼠标左键按下 设置开始画线标志 start = Input.mousePosition;//记录按下位置 end = Input.mousePosition;//鼠标当前位置 }else if (Input.GetMouseButtonUp(0)){drawFlag = false;//如果鼠标左键放开 结束画线 }if (Input.GetKeyDown(KeyCode.M)){StartCoroutine(CutImage());}}//绘制框选 void OnPostRender(){//画线这种操作推荐在OnPostRender()里进行 而不是直接放在Update,所以需要标志来开启 if (drawFlag){end = Input.mousePosition;//鼠标当前位置 }GL.PushMatrix();//保存摄像机变换矩阵 if (!rMat)return;rMat.SetPass(0);GL.LoadPixelMatrix();//设置用屏幕坐标绘图 GL.Begin(GL.LINES);GL.Color(rColor);//设置方框的边框颜色 边框不透明 GL.Vertex3(start.x, start.y, 0);GL.Vertex3(end.x, start.y, 0);GL.Vertex3(end.x, start.y, 0);GL.Vertex3(end.x, end.y, 0);GL.Vertex3(end.x, end.y, 0);GL.Vertex3(start.x, end.y, 0);GL.Vertex3(start.x, end.y, 0);GL.Vertex3(start.x, start.y, 0);GL.End();GL.PopMatrix();//恢复摄像机投影矩阵 }IEnumerator CutImage(){string date = System.DateTime.Now.ToString("yyyyMMddHHmmss");//图片大小 cutImage = new Texture2D((int)(end.x - start.x), (int)(start.y - end.y), TextureFormat.RGB24, true);//坐标左下角为0 rect = new Rect((int)start.x, Screen.height - (int)(Screen.height - end.y), (int)(end.x - start.x), (int)(start.y - end.y));yield return new WaitForEndOfFrame();cutImage.ReadPixels(rect, 0, 0, true);cutImage.Apply();yield return cutImage;byte[] byt = cutImage.EncodeToPNG();//保存截图 File.WriteAllBytes(Application.streamingAssetsPath + "/ImageName" + date + ".png", byt);}}
}
二、第二种方法
原理都差不多,第二种扩展性更好一些。
需要创建4个UI,来充当线框。并设置好Anchors。
第一步:
创建一个父节点,以及子节点。如下图:


第二步
分别创建4个UI,充当4边线框,并设置每个边其Anchors。如下图:




第三步 代码
using System.Collections;
using System.Collections.Generic;
//using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.UI;public class MarkerPointSet : MonoBehaviour
{private Vector3 m_Point;// private PointBase m_PointBase;private List<GameObject> m_Images = new List<GameObject>();List<Texture2D> m_AddListTexture = new List<Texture2D>();//private BaoGaoPoint m_BaoGaoPoint;private Texture2D m_screenShot;//画框截图public GameObject m_LineNode;public GameObject m_LeftLine;public GameObject m_RightLine;public GameObject m_DownLine;public GameObject m_UpLine;private Vector3 m_StartLine = Vector3.zero;private Vector3 m_EndLien = Vector3.zero;private bool m_IsScreens = false;private bool m_IsMouseEnd = false;void Start(){m_IsScreens = true;}private void Update(){if (m_IsScreens == true){m_EndLien = Input.mousePosition;if (Input.GetMouseButtonDown(0)){m_StartLine = Input.mousePosition;m_LineNode.gameObject.SetActive(true);m_IsMouseEnd = true;}else if(Input.GetMouseButtonUp(0)){if (m_IsMouseEnd == true){m_EndLien = Input.mousePosition;m_IsScreens = false;m_IsMouseEnd = false;//m_Buttons.SetActive(true);//m_Buttons.transform.position = Input.mousePosition;int _x = (int)m_StartLine.x;int _y = (int)m_StartLine.y;int _w = (int) (m_StartLine.x - m_EndLien.x);int _h = (int)(m_StartLine.y - m_EndLien.y);if (_w < 0){_w = Mathf.Abs(_w);}else{_x -= _w;}if (_h < 0){_h = Mathf.Abs(_h);}else{_y -= _h;}StartCoroutine(CaptureScreen(new Rect(_x,_y,_w,_h)));}}if (m_IsMouseEnd == true){UpdateLine();}}}private void UpdateLine(){m_LeftLine.transform.position = m_StartLine;m_DownLine.transform.position = m_StartLine;m_RightLine.transform.position = m_EndLien;m_UpLine.transform.position = m_EndLien;float _x = m_StartLine.x - m_EndLien.x;float _y = m_StartLine.y - m_EndLien.y;if (_x >=0){RectTransform _dtrans = m_DownLine.GetComponent<RectTransform>();_dtrans.sizeDelta = new Vector2(_x,2f);RectTransform _utrans = m_UpLine.GetComponent<RectTransform>();_utrans.sizeDelta = new Vector2(_x, 2f);_dtrans.localScale = new Vector3(-1f,1f,1f);_utrans.localScale = new Vector3(-1f, 1f, 1f);} else{_x = Mathf.Abs(_x);RectTransform _dtrans = m_DownLine.GetComponent<RectTransform>();_dtrans.sizeDelta = new Vector2(_x, 2f);RectTransform _utrans = m_UpLine.GetComponent<RectTransform>();_utrans.sizeDelta = new Vector2(_x, 2f);_dtrans.localScale = new Vector3(1f, 1f, 1f);_utrans.localScale = new Vector3(1f, 1f, 1f);}if (_y >= 0){RectTransform _dtrans = m_LeftLine.GetComponent<RectTransform>();_dtrans.sizeDelta = new Vector2(2f, _y);RectTransform _utrans = m_RightLine.GetComponent<RectTransform>();_utrans.sizeDelta = new Vector2(2f, _y);_dtrans.localScale = new Vector3(1f, -1f, 1f);_utrans.localScale = new Vector3(1f, -1f, 1f);}else{_y = Mathf.Abs(_y);RectTransform _dtrans = m_LeftLine.GetComponent<RectTransform>();_dtrans.sizeDelta = new Vector2(2f, _y);RectTransform _utrans = m_RightLine.GetComponent<RectTransform>();_utrans.sizeDelta = new Vector2(2f, _y);_dtrans.localScale = new Vector3(1f, 1f, 1f);_utrans.localScale = new Vector3(1f, 1f, 1f);}}private IEnumerator CaptureScreen(Rect rect){yield return new WaitForEndOfFrame();//不显示UI截图RenderTexture _rt = new RenderTexture(1920,1080,0);Camera.main.targetTexture = _rt;//传到主摄像机上Camera.main.Render();//渲染RenderTexture.active = _rt;m_screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGB24, false);m_screenShot.ReadPixels(rect, 0, 0);m_screenShot.Apply();Camera.main.targetTexture = null;RenderTexture.active = null;Destroy(_rt);//m_Image.gameObject.SetActive(true);//m_Image.rectTransform.sizeDelta = new Vector2(m_screenShot.width, m_screenShot.height);//图片设置//m_Image.sprite = Sprite.Create(m_screenShot, new Rect(0, 0, m_screenShot.width, m_screenShot.height), Vector2.zero);yield break;}}
项目链接: link:
总结
好记性不如烂笔头
相关文章:
unity 自由框选截图(两种方法,亲测有效)
提示:文章有错误的地方,还望诸位大神不吝指教! 文章目录 前言一、第一种方法(1)简介GL(2) GL 用法:(3)具体代码 二、第二种方法第一步:第二步第三…...
项目代码规范
editorconfig EditorConfig 是一种用于统一不同编辑器和 IDE 的代码风格的文件格式和插件,帮助开发人员在不同的编辑器和 IDE 中保持一致的代码风格,从而提高代码的可读性和可维护性 # EditorConfig is awesome: https://EditorConfig.org root true[…...
STM32的BKP与RTC简介
芯片的供电引脚 引脚表橙色的是芯片的供电引脚,其中VSS/VDD是芯片内部数字部分的供电,VSSA/VDDA是芯片内部模拟部分的供电,这4组以VDD开头的供电都是系统的主电源,正常使用时,全部都要接3.3V的电源上,VBAT是…...
11.Java安卓程序设计-基于SSM框架的Android平台健康管理系统的设计与实现
摘要 随着人们生活水平的提高和健康意识的增强,健康管理系统在日常生活中扮演着越来越重要的角色。本研究旨在设计并实现一款基于SSM框架的Android平台健康管理系统,为用户提供全面的健康监测和管理服务。 在需求分析阶段,我们明确了系统的…...
jetbrains卡顿(Pycharm等全家桶)终极解决方案,肯定解决!非常肯定!
话越短,越有用,一共四种方案,肯定能解决!!!非常肯定!! 下面四种解决方案,笔者按照实际体验后的结果,按照优先级从高到低排序。你只要按顺序试试就知道了。 m…...
c++的排序算法
一:merge 是 C STL 中的一个算法函数,用于将两个已排序的序列合并成一个有序序列。 template<class InputIterator1, class InputIterator2, class OutputIterator, class Compare> OutputIterator merge(InputIterator1 first1, InputIterator1 …...
YOLOv5独家原创改进:SPPF自研创新 | SPPF与感知大内核卷积UniRepLK结合,大kernel+非膨胀卷积提升感受野
💡💡💡本文自研创新改进:SPPF与感知大内核卷积UniRepLK结合,大kernel+非膨胀卷积,使SPPF增加大kernel,提升感受野,最终提升检测精度 收录 YOLOv5原创自研 https://blog.csdn.net/m0_63774211/category_12511931.html 💡💡💡全网独家首发创新(原创),…...
【C/PTA —— 15.结构体2(课外实践)】
C/PTA —— 15.结构体2(课外实践) 7-1 一帮一7-2 考试座位号7-3 新键表输出7-4 可怕的素质7-5 找出同龄者7-6 排队7-7 军训 7-1 一帮一 #include<stdio.h> #include<string.h>struct student {int a;char name[20]; };struct student1 {int …...
艾泊宇产品战略:适应新消费时代,产品战略指南以应对市场挑战和提升盈利
赚钱越来越难,这是许多企业和个人都感到困惑的问题。 然而,艾泊宇产品战略告诉大家,我们不能把这个问题简单地归咎于经济环境或市场竞争,而是需要从更深层次去思考和解决。 本文将从多个角度去剖析这个问题,并探讨在…...
使用autodl服务器,两个3090显卡上运行, Yi-34B-Chat-int4模型,并使用vllm优化加速,显存占用42G,速度23 words/s
1,演示视频地址 https://www.bilibili.com/video/BV1Hu4y1L7BH/ 使用autodl服务器,两个3090显卡上运行, Yi-34B-Chat-int4模型,用vllm优化,增加 --num-gpu 2,速度23 words/s 2,使用3090显卡 和…...
ORACLE数据库实验总集 实验六 SQL 语句应用
一、 实验目的 (1) 掌握数据的插入(INSERT)、 修改(UPDATE) 和删除(DELETE) 操作。 (2) 掌握不同类型的数据查询(SELECT) 操作。 二、…...
[FPGA 学习记录] 快速开发的法宝——IP核
快速开发的法宝——IP核 文章目录 1 IP 核是什么2 为什么要使用 IP 核3 IP 核的存在形式4 IP 核的缺点5 Quartus II 软件下 IP 核的调用6 Altera IP 核的分类 在本小节当中,我们来学习一下 IP 核的相关知识。 IP 核在 FPGA 开发当中应用十分广泛,它被称为…...
每日一题:LeetCode-11.盛水最多的容器
每日一题系列(day 13) 前言: 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🌈 🔎…...
查看电脑cuda版本
1.找到NVODIA控制面板 输入NVIDIA搜索即可 出现NVIDIA控制面板 点击系统信息 2.WINR 输入nvidia-smi 检查了一下,电脑没用过GPU,连驱动都没有 所以,装驱动…… 选版本,下载 下载后双击打开安装 重新输入nvidia-smi 显示如下…...
centos7 docker Mysql8 搭建主从
Mysql8 搭建主从 docker的安装docker-compose的安装安装mysql配置主从在master配置在slave中配置在master中创建同步用户在slave中连接 测试连接测试配置测试数据同步遇到的问题id重复错误执行事务出错,跳过错误my.cnf 不删除多余配置的错误可能用到的命令 docker的…...
CSS中 设置文字下划线 的几种方法
在网页设计和开发中,我们经常需要对文字进行样式设置,包括字体,颜色,大小等,其中,设置文字下划线是一种常见需求 一 、CSS种使用 text-decoration 属性来设置文字的装饰效果,包括下划线。 常用的取值&…...
Docker构建自定义镜像
创建一个docker-demo的文件夹,放入需要构建的文件 主要是配置Dockerfile文件 第一种配置方法 # 指定基础镜像 FROM ubuntu:16.04 # 配置环境变量,JDK的安装目录 ENV JAVA_DIR/usr/local# 拷贝jdk和java项目的包 COPY ./jdk8.tar.gz $JAVA_DIR/ COPY ./docker-demo…...
C#生成Token字符串
Token字符串来保证数据安全性,如身份验证、跨域访问等。但是由于Token字符串的长度比较长,可能会占用过多的空间和带宽资源,因此我们需要生成短的Token字符串 方法一:使用Base64编码 Base64编码是一种常用的编码方式,…...
文献速递:多模态影像组学文献分享:生成一种多模态人工智能模型以区分甲状腺良性和恶性滤泡性肿瘤:概念验证研究
文献速递:多模态影像组学文献分享:生成一种多模态人工智能模型以区分甲状腺良性和恶性滤泡性肿瘤:概念验证研究 文献速递介绍 近年来,人工智能(AI)领域日益被探索,作为一种增强传统医学诊断和…...
Docker创建RocketMQ和RocketMQ控制台
安装RocketMQ 安装最新版本的RocketMQ(名为RocketMQ)在Docker上的过程大致可以分为以下步骤: 1. 准备工作 确保你的系统中已经安装了Docker。可以通过运行 docker --version 来验证Docker是否已安装及其版本信息。 2. 拉取RocketMQ镜像 …...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
Java线上CPU飙高问题排查全指南
一、引言 在Java应用的线上运行环境中,CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时,通常会导致应用响应缓慢,甚至服务不可用,严重影响用户体验和业务运行。因此,掌握一套科学有效的CPU飙高问题排查方法&…...
#Uniapp篇:chrome调试unapp适配
chrome调试设备----使用Android模拟机开发调试移动端页面 Chrome://inspect/#devices MuMu模拟器Edge浏览器:Android原生APP嵌入的H5页面元素定位 chrome://inspect/#devices uniapp单位适配 根路径下 postcss.config.js 需要装这些插件 “postcss”: “^8.5.…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...
初探Service服务发现机制
1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能:服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源…...
逻辑回归暴力训练预测金融欺诈
简述 「使用逻辑回归暴力预测金融欺诈,并不断增加特征维度持续测试」的做法,体现了一种逐步建模与迭代验证的实验思路,在金融欺诈检测中非常有价值,本文作为一篇回顾性记录了早年间公司给某行做反欺诈预测用到的技术和思路。百度…...
【从零开始学习JVM | 第四篇】类加载器和双亲委派机制(高频面试题)
前言: 双亲委派机制对于面试这块来说非常重要,在实际开发中也是经常遇见需要打破双亲委派的需求,今天我们一起来探索一下什么是双亲委派机制,在此之前我们先介绍一下类的加载器。 目录 编辑 前言: 类加载器 1. …...
