前言
之前Unity3d的程序在win pc上打开网页一般使用EmbeddedBrowser插件,也算是比较好用的,不过经过查找我发现3D WebView for Windows and macOS (Web Browser)插件也很不错。支持?Vuplex VR/AR 浏览器的相同代码,轻松地在 Windows 和 macOS 上以 3D 形式渲染 Web 内容并与之进行交互。支持Android、iOS、Windows、macOS?和?UWP/Hololens这些平台,不过这里的版本仅支持Windows and macOS平台。其余的平台需要下载其他版本。支持调用键盘和鼠标事件,以编程方式调整大小、缩放、滚动和后退/前进;支持在当前页面的上下文中执行 JavaScript; 支持将消息从JavaScript(网页) 发送到 C# 或者反向发送;支持监听浏览器事件,例如TitleChanged、UrlChanged以及PageLoadFailed;支持查看 PDF;支持在世界坐标系内和UI画布上打开网页。功能很齐全,但是价格也很不美丽。
效果
这是打开网页:
VR中应用:
打开网页
这里就使用CanvasWebViewPrefab?快速上手,打开网页它们会自动渲染为 Texture2D 并处理用户互动(单击、滚动、悬停、拖动)。
准备场景
新建一个场景,并新建一个Canvas。
导入插件后,找到Assets\Vuplex\WebView\Core\Prefabs\Resources\CanvasWebViewPrefab.prefab预设:
将其拖到Canvas下。
编写代码
这里我们在运行就打开Unity官网:
using UnityEngine;
using Vuplex.WebView;
public class test : MonoBehaviour
{
public CanvasWebViewPrefab canvasWebView;
async void Start()
{
await canvasWebView.WaitUntilInitialized();
canvasWebView.WebView.LoadUrl("https://unity.cn/");
}
}
将脚本组件挂到场景,并将canvasWebView关联起来。
运行起来效果:
Unity执行页面JS
这个主要调用ExecuteJavaScript来实现,该函数有两个重载:
void?ExecuteJavaScript(string?javaScript,?Action<string>?callback)
Task<string>?ExecuteJavaScript(string?javaScript)
为了运行 JavaScript,必须首先加载网页。您可以使用WaitForNextPageLoadToFinish()或LoadProgressChanged事件在页面加载后运行 JavaScript。
如:
await webViewPrefab.WaitUntilInitialized();
await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
var headerText = await webViewPrefab.WebView.ExecuteJavaScript("document.getElementsByTagName('h1')[0].innerText");
Debug.Log("H1 text: " + headerText);
这就是找到标签名 h1并输出它的文本。
Unity与网页消息通信
使用该插件是可以实现 Unity与网页的双向通信,只不过要对接完美,需要两边的开发者协商好通信消息以及格式。
Unity向网页发消息
从 Unity向 网页 发送消息是使用PostMessage()函数来实现。
发送消息的 C# 脚本:
async void Start() {
var webViewPrefab = GameObject.Find("WebViewPrefab").GetComponent<WebViewPrefab>();
// Wait for the WebViewPrefab to initialize, because the WebViewPrefab.WebView property
// is null until the prefab has initialized.
await webViewPrefab.WaitUntilInitialized();
// Send a message after the page has loaded.
await webViewPrefab.WebView.WaitForNextPageLoadToFinish();
webViewPrefab.WebView.PostMessage("{\"type\": \"greeting\", \"message\": \"Hello from C#!\"}");
}
在网页端,通过对象?message事件监听消息的 JavaScript :
if (window.vuplex) {
addMessageListener();
} else {
window.addEventListener('vuplexready', addMessageListener);
}function addMessageListener() {
window.vuplex.addEventListener('message', function(event) {
let json = event.data;
// > JSON received: { "type": "greeting", "message": "Hello from C#!" }
console.log('JSON received: ' + json);
});
}
网页向Unity发消息
3D WebView 有一个内置的window.vuplex.postMessage() JavaScript API,可用于将消息从 网页发送到 Unity。由于它内置在浏览器中,因此您无需在页面中包含任何第三方脚本即可使用它。以下为发消息示例脚本:
// The window.vuplex object gets created when the page starts loading,// so we double-check that it exists before using it here.// You can skip this step if you're sending a message after the page has loaded.
if (window.vuplex) {
// The window.vuplex object already exists, so go ahead and send the message.
sendMessageToCSharp();
} else {
// The window.vuplex object hasn't been initialized yet because the page is still
// loading, so add an event listener to send the message once it's initialized.
window.addEventListener('vuplexready', sendMessageToCSharp);
}function sendMessageToCSharp() {
// This object passed to postMessage() automatically gets serialized as JSON
// and is emitted via the C# MessageEmitted event. This API mimics the window.postMessage API.
window.vuplex.postMessage({ type: 'greeting', message: 'Hello from JavaScript!' });
}
在Unity端通过MessageEmitted 事件的监听来接收网页发送过来的消息。
Unity 中接收该消息脚本示例:
async void Start() {
// This assumes that there's a WebViewPrefab already in the scene.
var webViewPrefab = GameObject.Find("WebViewPrefab").GetComponent<WebViewPrefab>();
// Wait for the WebViewPrefab to initialize, because the WebViewPrefab.WebView property
// is null until the prefab has initialized.
await webViewPrefab.WaitUntilInitialized();
webViewPrefab.WebView.MessageEmitted += (sender, eventArgs) => {
// > JSON received: { "type": "greeting", "message": "Hello from JavaScript!" }
Debug.Log("JSON received: " + eventArgs.Value);
};
}
其它
Unity模拟点击网页
通过click函数来实现:
void?Click(Vector2?normalizedPoint,?bool?preventStealingFocus?= false)
示例脚本:
// Click in the exact center of the page.
webViewPrefab.WebView.Click(new Vector2(0.5f, 0.5f));
// Click in the upper right quadrant of the page// and prevent stealing focus from another webview.
webViewPrefab.WebView.Click(new Vector2(0.75f, 0.25f), true);
只不过normalizedPoint是采用标准化点而不是像素坐标,即Vector2? 每个元素的取值范围 0–1。
Unity操作网页文本
选择所有文本,具体取决于页面的焦点元素
webViewPrefab.WebView.SelectAll();
将选定的文本复制到剪贴板:
webViewPrefab.WebView.Copy();
将选定的文本复制到剪贴板并将其删除:
webViewPrefab.WebView.Cut();