目录
截图参考:Unity3D 局部截图、全屏截图、带UI截图三种方法_unity 截图_野区捕龙为宠的博客-CSDN博客
文档下载: Unity WebGL 生成doc保存到本地电脑_unity webgl 保存文件_野区捕龙为宠的博客-CSDN博客
中文输入:Unity WebGL中文输入 支持输入法跟随 支持全屏(内附Dome)_unity中文插件-CSDN博客
话不多说直接上代码:
- private void Awake()
- {
- //点击提交下载 按钮
- Btn_download.onClick.AddListener(() =>
- {
- Btn_download.gameObject.SetActive(value: false);
-
- GetComponent<Capture_Long>().Cap_LongTex();//截图拼图
- //下载PDF
- GetComponent<Capture_Long>().CapCallBack = ((png_byte) =>
- {
- string filename = CQOOC.Instance.userName + "_" + DateTime.Now.ToString("g");
- Btn_download.gameObject.SetActive(true);
- Application.ExternalCall("downloadPng", png_byte, filename);//调用 webgl 方法
-
- // Debug.Log("filename="+ filename);
- });
- //上传 截图
- GetComponent<Capture_Long>().CapByteCallBack = ((png_byte) =>
- {
- string filename = CQOOC.Instance.userName + "_" + DateTime.Now.ToString("g");
- Debug.Log("filename=" + filename);
- //上传实验报告 截图
- CQOOC.Instance.UploadFile(png_byte, filename+".png", ((b) => {
- if (b)
- {
- Debug.Log("上传截图成功!");
- }
- else
- {
- Debug.Log("上传截图失败!");
- }
- }));
-
- //上传实验报告 数据
- CQOOC.Instance.UploadData_((b) => {
- if (b)
- {
- UITipDialogMini.Instance.SetState(true, "提交数据成功!");
- }
- else
- {
- UITipDialogMini.Instance.SetState(true, "提交数据失败!");
- }
- });
-
- });
- });
- DateTime now = DateTime.Now.AddMinutes(-15);
- string formattedTime = now.ToString("yyyy 年 M 月 d 日 HH:mm:ss");
- text_StartTime.text = formattedTime;
-
- DateTime now02 = DateTime.Now;
- string formattedTime02 = now02.ToString("yyyy 年 M 月 d 日 HH:mm:ss");
- text_EndTime.text = formattedTime02;
-
- // text_StartTime.text = DateTime.Now.AddMinutes(-15).ToString("F");
- //text_EndTime.text = DateTime.Now.ToString("F");
-
- text_UserName.text = CQOOC.Instance.userName;
- text_Score.text = UnityEngine.Random.Range(80f, 95f).ToString("0");
- }
-

由于图片太长需要拼接
- using System;
- using System.Collections;
- using UnityEngine;
- using UnityEngine.UI;
-
- public class Capture_Long : MonoBehaviour
- {
- public RectTransform svrt;
- public RectTransform contentRT;
- public Action<string> CapCallBack;
- public Action<byte[]> CapByteCallBack;
- public Vector2 vec;
-
- /// <summary>
- /// 接长图,进行拼接
- /// </summary>
- /// <param name="SVRT">Scroll Rect</param>
- /// <param name="ContentRT">Content</param>
- public void Cap_LongTex()
- {
- StartCoroutine(Cap(svrt, contentRT));
- }
- private IEnumerator Cap(RectTransform SVRT, RectTransform ContentRT)
- {
- //画布中的高度 950
- float SV_Y = SVRT.sizeDelta.y;
-
- //content显示的区域高度 0
- float Content_Y = ContentRT.anchoredPosition.y;
- //图片的整体高度 2660
- float Content_Height = contentRT.sizeDelta.y+ SV_Y;
-
- var mult = (float)(Content_Height / SV_Y);
- //整数倍
- int mult_int = (int)mult;
- //最后的小数倍
- float mult_float = mult - mult_int;
-
- //滚动条的宽度
- float verticalScrollbar_weight = SVRT.GetComponent<ScrollRect>().verticalScrollbar.GetComponent<RectTransform>().sizeDelta.x;
-
- yield return new WaitForEndOfFrame();
-
- //合成图片的总高度
- int totalHeight = (int)Content_Height;
- Texture2D endTex = new Texture2D((int)vec.y, totalHeight, TextureFormat.RGBA32, false);
- int x = 0, y = 0;
- Color32[] colors;
-
- //整数倍的截图
- for (int i = 0; i < mult_int; i++)
- {
- ContentRT.anchoredPosition = new Vector2(0, SV_Y * i);
- yield return new WaitForEndOfFrame();
- //Rect rect_int = new Rect(Screen.width / 2 - SVRT.sizeDelta.x / 2 + SVRT.anchoredPosition.x, Screen.height / 2 - SVRT.sizeDelta.y / 2 + SVRT.anchoredPosition.y, SVRT.sizeDelta.x - verticalScrollbar_weight, SVRT.sizeDelta.y);
- //Rect rect_int = new Rect(420, 166.5f, 1365, SVRT.sizeDelta.y);
- Rect rect_int = new Rect(420, vec.x, vec.y, SVRT.sizeDelta.y);
-
- var tex_int = CaptureScreenshot(rect_int, i + "");
-
- //合成
- colors = tex_int.GetPixels32(0);
- if (i > 0)
- {
- y -= tex_int.height;
- }
- else
- {
- y = totalHeight - tex_int.height;
- }
- endTex.SetPixels32(x, y, tex_int.width, tex_int.height, colors);
- }
-
- //小数倍的截图
- ContentRT.anchoredPosition = new Vector2(0, SV_Y * (mult - 1));
- yield return new WaitForEndOfFrame();
- //Rect rect_float = new Rect(Screen.width / 2 - SVRT.sizeDelta.x / 2 + SVRT.anchoredPosition.x, Screen.height / 2 - SVRT.sizeDelta.y / 2 + SVRT.anchoredPosition.y, SVRT.sizeDelta.x - verticalScrollbar_weight, SVRT.sizeDelta.y * mult_float);
- Rect rect_float = new Rect(420, vec.x, vec.y, SVRT.sizeDelta.y * mult_float);
-
- var tex_float = CaptureScreenshot(rect_float, "end");
-
- //合成
- colors = tex_float.GetPixels32(0);
- y -= tex_float.height;
- endTex.SetPixels32(x, y, tex_float.width, tex_float.height, colors);
- endTex.Apply();
- byte[] bytes = endTex.EncodeToPNG();//然后将这些纹理数据,成一个png图片文件
- var strPng = Convert.ToBase64String(bytes);
-
- #if UNITY_EDITOR
- string filename = Application.dataPath + "/PNG/合成.png";
- System.IO.File.WriteAllBytes(filename, bytes);
- Debug.Log(string.Format("截屏了一张图片: {0}", filename));
- #endif
-
- SVRT.GetComponent<ScrollRect>().verticalNormalizedPosition = 1;
- CapCallBack?.Invoke(strPng);
-
- CapByteCallBack?.Invoke(bytes);
- }
-
- /// <summary>
- /// 开始截图
- /// </summary>
- /// <returns>The screenshot2.</returns>
- /// <param name="rect">Rect.截图的区域,左下角为o点</param>
- private Texture2D CaptureScreenshot(Rect rect, string name)
- {
- //Debug.Log(rect.ToString());
- Texture2D screenShot = new Texture2D((int)rect.width, (int)rect.height, TextureFormat.RGBA32, false);//先创建一个的空纹理,大小可根据实现需要来设置
- screenShot.ReadPixels(rect, 0, 0);//读取屏幕像素信息并存储为纹理数据,
- screenShot.Apply();
-
- #if UNITY_EDITOR
- byte[] bytes = screenShot.EncodeToPNG();//然后将这些纹理数据,成一个png图片文件
- string filename = Application.dataPath + "/PNG/Screenshot" + name + ".png";
- System.IO.File.WriteAllBytes(filename, bytes);
- //Debug.Log(string.Format("截屏了一张图片: {0}", filename));
- #endif
- return screenShot;
- }
- }
3.web端代码
- <!DOCTYPE html>
- <html lang="en-us">
- <head>
- <meta charset="utf-8">
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <title>XiaoLuoDai</title>
- <link rel="shortcut icon" href="TemplateData/favicon.ico">
- <link rel="stylesheet" href="TemplateData/style.css">
- <script src="TemplateData/UnityProgress.js"></script>
- <script src="Build/UnityLoader.js"></script>
- <script>
-
- var unityInstance = UnityLoader.instantiate("unityContainer", "Build/WebGL.json", {onProgress: UnityProgress});
-
- function GetWebGLURI()
- {
- unityInstance.SendMessage("CQOOC", "GetURI_CallBack", window.location.href);
- }
- </script>
- <script src="https://cdn.bootcss.com/jspdf/1.3.4/jspdf.debug.js"></script>
- <script>
- function downloadPng(base64, filename) {
- var baseData = 'data:image/png;base64,' + base64
- ///
- // 获取图片文件的宽高
- ///
- let image = new Image();
- image.src = baseData;
- image.onload = function () {
- console.log(image.width, image.height);
- var contentWidth = image.width;
- var contentHeight = image.height;
-
- //一页pdf显示html页面生成的canvas高度;
- var pageHeight = contentWidth / 592.28 * 841.89;
- //未生成pdf的html页面高度
- var leftHeight = contentHeight;
- //页面偏移
- var position = 0;
- //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
- var imgWidth = 595.28;
- var imgHeight = 592.28 / contentWidth * contentHeight;
- //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
- //当内容未超过pdf一页显示的范围,无需分页
-
- var pdf = new jsPDF('', 'pt', 'a4');
- if (leftHeight < pageHeight) {
- pdf.addImage(baseData, 'PNG', 0, 0, imgWidth, imgHeight);
- } else {
- while (leftHeight > 0) {
- pdf.addImage(baseData, 'PNG', 0, position, imgWidth, imgHeight)
- leftHeight -= pageHeight;
- position -= 841.89;
- //避免添加空白页
- if (leftHeight > 0) {
- pdf.addPage();
- }
- }
- }
- pdf.save(filename + ".pdf")
- }
- }
- </script>
- <script>
- function FullScreenMetthod()//中文输入
- {
- document.getElementById('unityContainer').requestFullscreen();
- }
- </script>
- </head>
- <body>
- <div class="webgl-content">
- <div id="unityContainer" style="width: 1920px; height: 1080px"></div>
- <div class="footer">
- <div class="webgl-logo"></div>
- <div class="fullscreen" onclick="FullScreenMetthod()"></div>
- <div class="title">XiaoLuoDai</div>
- </div>
- </div>
- </body>
- </html>