最近几天公司要做unityweb端下载pdf文档的需求。查了很多网站发现都没有一个实例。自己研究了研究做了一个小实例分享一下。可能对于前端大佬来说太简单了,不过对于u3d程序来说对于js和html不太了解的话,做起来就挺痛苦了。
首先unity与js通信的现在用了新的结构方法。这网上有很多介绍的,我就不再介绍了,直接放代码
这段需要在放.jslib中
mergeInto(LibraryManager.library, {
LoadTextPDFBtn : function (t0, n0) {
var tt0 = UTF8ToString(t0);
var nn0 = UTF8ToString(n0);
LoadTextPDF(tt0,nn0);
},
LoadTextAndImagePDFBtn : function (t1,i1, n1) {
var tt1 = UTF8ToString(t1);
var ii1 = UTF8ToString(i1);
var nn1 = UTF8ToString(n1);
LoadTextAndImagePDF(tt1,ii1,nn1);
},
LoadImageBtn : function (i2, n2) {
var ii2 = UTF8ToString(i2);
var nn2 = UTF8ToString(n2);
LoadImage(ii2,nn2);
}
});
c#代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.UI;
public class GameMain2 : MonoBehaviour
{
public Button textBtn, tAndIBtn, imageBtn;
public Sprite picture0, picture1, picture2, picture3, picture4, picture5;
public Image image;
public InputField inputField;
public ToggleGroup toggleGroup;
public InputField documentIF;
public Text log;
byte[] photoByte;
void Awake()
{
textBtn.onClick.AddListener(Creator);
tAndIBtn.onClick.AddListener(DownLoad);
imageBtn.onClick.AddListener(ImageBtn);
}
void Start()
{
documentIF.text = "test";
Texture2D temp = picture0.texture;
photoByte = temp.EncodeToPNG();
GetBase64String();
image.sprite = picture0;
}
[DllImport("__Internal")]
private static extern void LoadImageBtn(string imageData,string name);
private void ImageBtn()
{
if (photoByte != null)
{
string imageData = Convert.ToBase64String(photoByte);
if (imageData != null)
{
LoadImageBtn(imageData, documentIF.text + "_Image.jpg");
}
}
}
public void ChangeImage(bool isOn)
{
if (!isOn) return;
foreach (var item in toggleGroup.ActiveToggles())
{
switch (item.name)
{
case "0":
Texture2D temp0 = picture0.texture;
photoByte = temp0.EncodeToPNG();
GetBase64String();
image.sprite = picture0;
break;
case "1":
Texture2D temp1 = picture1.texture;
photoByte = temp1.EncodeToPNG();
GetBase64String();
image.sprite = picture1;
break;
case "2":
Texture2D temp2 = picture2.texture;
photoByte = temp2.EncodeToPNG();
GetBase64String();
image.sprite = picture2;
break;
case "3":
Texture2D temp3 = picture3.texture;
photoByte = temp3.EncodeToPNG();
GetBase64String();
image.sprite = picture3;
break;
case "4":
Texture2D temp4 = picture4.texture;
photoByte = temp4.EncodeToPNG();
GetBase64String();
image.sprite = picture4;
break;
case "5":
Texture2D temp5 = picture5.texture;
photoByte = temp5.EncodeToPNG();
GetBase64String();
image.sprite = picture5;
break;
default:
break;
}
}
}
public bool isOn = true;
[DllImport("__Internal")]
private static extern void LoadTextAndImagePDFBtn(string textData, string imageData, string name);
private void DownLoad()
{
string imageData = GetBase64String();
if (imageData != null)
{
if (isOn)
{
if (inputField.text != "")
{
LoadTextAndImagePDFBtn(inputField.text, imageData, documentIF.text + "_TestAndImage.pdf");
}
else
{
LoadTextAndImagePDFBtn("test_测试_" + Time.deltaTime, imageData, documentIF.text + "_TestAndImage.pdf");
}
}
}
}
private string GetBase64String()
{
if (photoByte != null)
{
string data = Convert.ToBase64String(photoByte);
log.text = data;
return data;
}
log.text = "没成功!";
return null;
}
[DllImport("__Internal")]
private static extern void LoadTextPDFBtn(string textData, string name);
private void Creator()
{
if (inputField.text != "")
{
LoadTextPDFBtn(inputField.text, documentIF.text + "_Test.pdf");
}
else
{
LoadTextPDFBtn("test_测试_" + Time.deltaTime, documentIF.text + "_Test.pdf");
}
}
}
这样就可以打包了。
后面的代码要在index.html修改,用vs打开后修改。
<!DOCTYPE html>
<html lang="en-us">
<head>
<meta charset="utf-8">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Unity WebGL Player | WebTestOne</title>
<link rel="shortcut icon" href="TemplateData/favicon.ico">
<link rel="stylesheet" href="TemplateData/style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/1.5.3/jspdf.debug.js" integrity="sha384-NaWTHo/8YCBYJ59830LTz/P4aQZK1sS0SneOgAvhsIl3zBu8r9RevNg5lHCHAuQ/" crossorigin="anonymous"></script>
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/jspdf"></script>
<script src="https://cdn.jsdelivr.net/npm/vxe-table-plugin-export-pdf/fonts/source-han-sans-normal.js"></script>
<script>
function LoadTextPDF(textData, name) {
var doc = new jsPDF();
doc.setFontSize(40);
doc.addFont('SourceHanSans-Normal.ttf', 'SourceHanSans-Normal', 'normal');
doc.setFont('SourceHanSans-Normal');
doc.text(textData, 20, 20);
doc.save(name);
}
function LoadTextAndImagePDF(textData, imageData, name) {
var doc = new jsPDF();
doc.setFontSize(40);
doc.addFont('SourceHanSans-Normal.ttf', 'SourceHanSans-Normal', 'normal');
doc.setFont('SourceHanSans-Normal');
doc.text(textData, 20, 20);
var imgData = 'data:image/png;base64,' + imageData;
doc.addImage(imgData, 'PNG', 20, 40, 180, 160);
doc.save(name);
}
function LoadImage(imageData, name) {
var contentType = 'image/jpeg';
function fixBinary(bin) {
var length = bin.length;
var buf = new ArrayBuffer(length);
var arr = new Uint8Array(buf);
for (var i = 0; i < length; i++) {
arr[i] = bin.charCodeAt(i);
}
return buf;
}
var binary = fixBinary(atob(imageData));
var export_blob = new Blob([binary], { type: contentType });
var link = document.createElement('a');
link.download = name;
link.innerHTML = 'DownloadFile';
link.setAttribute('id', 'ImageDownloaderLink');
link.href = window.URL.createObjectURL(export_blob);
link.onclick = function () {
var child = document.getElementById('ImageDownloaderLink');
child.parentNode.removeChild(child);
};
link.style.display = 'none';
document.body.appendChild(link);
link.click();
window.URL.revokeObjectURL(link.href);
}
</script>
</head>
<body>
<div id="unity-container" class="unity-desktop">
<canvas id="unity-canvas" width=1920 height=1080></canvas>
<div id="unity-loading-bar">
<div id="unity-logo"></div>
<div id="unity-progress-bar-empty">
<div id="unity-progress-bar-full"></div>
</div>
</div>
<div id="unity-warning"> </div>
<div id="unity-footer">
<div id="unity-webgl-logo"></div>
<div id="unity-fullscreen-button"></div>
<div id="unity-build-title">WebTestOne</div>
</div>
</div>
<script>
var container = document.querySelector("#unity-container");
var canvas = document.querySelector("#unity-canvas");
var loadingBar = document.querySelector("#unity-loading-bar");
var progressBarFull = document.querySelector("#unity-progress-bar-full");
var fullscreenButton = document.querySelector("#unity-fullscreen-button");
var warningBanner = document.querySelector("#unity-warning");
// Shows a temporary message banner/ribbon for a few seconds, or
// a permanent error message on top of the canvas if type=='error'.
// If type=='warning', a yellow highlight color is used.
// Modify or remove this function to customize the visually presented
// way that non-critical warnings and error messages are presented to the
// user.
function unityShowBanner(msg, type) {
function updateBannerVisibility() {
warningBanner.style.display = warningBanner.children.length ? 'block' : 'none';
}
var div = document.createElement('div');
div.innerHTML = msg;
warningBanner.appendChild(div);
if (type == 'error') div.style = 'background: red; padding: 10px;';
else {
if (type == 'warning') div.style = 'background: yellow; padding: 10px;';
setTimeout(function() {
warningBanner.removeChild(div);
updateBannerVisibility();
}, 5000);
}
updateBannerVisibility();
}
var buildUrl = "Build";
var loaderUrl = buildUrl + "/test33.loader.js";
var config = {
dataUrl: buildUrl + "/test33.data",
frameworkUrl: buildUrl + "/test33.framework.js",
codeUrl: buildUrl + "/test33.wasm",
streamingAssetsUrl: "StreamingAssets",
companyName: "LBZY",
productName: "WebTestOne",
productVersion: "0.1",
showBanner: unityShowBanner,
};
// By default Unity keeps WebGL canvas render target size matched with
// the DOM size of the canvas element (scaled by window.devicePixelRatio)
// Set this to false if you want to decouple this synchronization from
// happening inside the engine, and you would instead like to size up
// the canvas DOM size and WebGL render target sizes yourself.
// config.matchWebGLToCanvasSize = false;
if (/iPhone|iPad|iPod|Android/i.test(navigator.userAgent)) {
// Mobile device style: fill the whole browser client area with the game canvas:
var meta = document.createElement('meta');
meta.name = 'viewport';
meta.content = 'width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, shrink-to-fit=yes';
document.getElementsByTagName('head')[0].appendChild(meta);
container.className = "unity-mobile";
canvas.className = "unity-mobile";
// To lower canvas resolution on mobile devices to gain some
// performance, uncomment the following line:
// config.devicePixelRatio = 1;
unityShowBanner('WebGL builds are not supported on mobile devices.');
} else {
// Desktop style: Render the game canvas in a window that can be maximized to fullscreen:
canvas.style.width = "1920px";
canvas.style.height = "1080px";
}
loadingBar.style.display = "block";
var script = document.createElement("script");
script.src = loaderUrl;
script.onload = () => {
createUnityInstance(canvas, config, (progress) => {
progressBarFull.style.width = 100 * progress + "%";
}).then((unityInstance) => {
loadingBar.style.display = "none";
fullscreenButton.onclick = () => {
unityInstance.SetFullscreen(1);
};
}).catch((message) => {
alert(message);
});
};
document.body.appendChild(script);
</script>
</body>
</html>
这样就可以了 ,一个简单的小demo就完成了,需要注意的就是图片的设置和图片能否被转换为base64。本人也是不太懂前端技术,这个只是简单能用的程度。如果有大佬看出问题欢迎指教。
和
最后放demo的链接:https://pan.baidu.com/s/1DSG5k-XAvSodmOXkM8ypDA
提取码:rsqe