当前位置:网站首页>Unity EmbeddedBrowser浏览器插件事件通讯
Unity EmbeddedBrowser浏览器插件事件通讯
2022-07-03 12:59:00 【foenix66】
Unity EmbeddedBrowser浏览器插件事件通讯
Embedded Browser浏览器插件是一款基于Chrome内核的内嵌浏览器,被许多开发语言和框架内嵌,为开发者提供方便的浏览网页支持。
Embedded Browser浏览器的工作方式是在后台运行浏览器进程,通过后台浏览器通讯解析网址,合成Texture贴图帧,传递给Unity,同时Unity可以调用接口,与浏览器进程进行交互。

Embedded这种集成方式区别于移动端的WebView集成方式(WebView是将一块屏幕空间开辟出来给WebView使用,调用者和WebView之间没有太多关联),提供更自由的整合渠道,可以在三维空间和实体表面显示网页,使用更灵活。
模拟鼠标输入
通常,无论是Screen Canvas还是三维Mesh表面的Embedded页面,插件已经提供了无缝的输入方式,内部提供的MapPointerToBrowser已经帮助用户将三维坐标转换到Browser平面坐标。
如果我们要自定义输入,如远程控制,通过远程主机发送控制坐标和鼠标按键通讯,驱动非用户硬件输入,通常做法是引入Windows DLL,通过模拟鼠标可以达到要求
#region DLLs
[DllImport("user32.dll")]
private static extern int SetCursorPos(int x, int y); //设置光标位置
[DllImport("user32.dll")]
private static extern bool GetCursorPos(ref int x, ref int y); //获取光标位置
[DllImport("user32.dll")]
static extern void mouse_event(MouseEventFlag flags, int dx, int dy, uint data, System.UIntPtr extraInfo); // 鼠标事件
// 方法参数说明
// VOID mouse_event(
// DWORD dwFlags, // motion and click options
// DWORD dx, // horizontal position or change
// DWORD dy, // vertical position or change
// DWORD dwData, // wheel movement
// ULONG_PTR dwExtraInfo // application-defined information
// );
public enum MouseEventFlag : uint
{
Move = 0x0001,
LeftDown = 0x0002,
LeftUp = 0x0004,
RightDown = 0x0008,
RightUp = 0x0010,
MiddleDown = 0x0020,
MiddleUp = 0x0040,
XDown = 0x0080,
XUp = 0x0100,
Wheel = 0x0800,
VirtualDesk = 0x4000,
Absolute = 0x8000
}
#endregion
调用代码
IEnumerator MouseClick(int x, int y)
{
SetCursorPos(x, y);
mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, System.UIntPtr.Zero);
yield return new WaitForSeconds(0.1f);
mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, System.UIntPtr.Zero);
}
这种方法在调试和使用时,由于窗口分辨率不是1:1全屏导致坐标映射错误、窗口不在前台、干扰正常鼠操作等等问题,使用非常不友好。
调用Embedded接口直接输入
查看源代码BrowserInput.cs,可以看到插件处理输入事件代码
private void HandleMouseInput() {
var handler = browser.UIHandler;
var mousePos = handler.MousePosition;
var currentButtons = handler.MouseButtons;
var mouseScroll = handler.MouseScroll;
if (mousePos != prevPos) {
BrowserNative.zfb_mouseMove(browser.browserId, mousePos.x, 1 - mousePos.y);
}
// ...
}
核心代码
BrowserNative.zfb_mouseMove(browser.browserId, mousePos.x, 1 - mousePos.y);
EmbeddedBrowser.Browser是虚拟给Unity使用的Browser对象,实际的浏览器对象是BrowserNative定义的一系列DLL接口。
browserId是一个数组索引,标记所有实际浏览器实例的列表
EmbeddedBrowser.Browser创建时加入allBrowsers列表
unsafeBrowserId = newId;
allBrowsers[unsafeBrowserId] = this;
按图索骥,BrowserNative包含了一系列浏览器接口,直接调用这些接口就可以扩展插件给我们定义的功能。
代码节选
/** * Reports the mouse's current location. * x and y are in the range [0,1]. (0, 0) is top-left, (1, 1) is bottom-right */
public delegate void Calltype_zfb_mouseMove(int id, float x, float y);
public static Calltype_zfb_mouseMove zfb_mouseMove;
public delegate void Calltype_zfb_mouseButton(int id, MouseButton button, bool down, int clickCount);
public static Calltype_zfb_mouseButton zfb_mouseButton;
/** Reports a mouse scroll. One "tick" of a scroll wheel is generally around 120 units. */
public delegate void Calltype_zfb_mouseScroll(int id, int deltaX, int deltaY);
public static Calltype_zfb_mouseScroll zfb_mouseScroll;
/** * Report a key down/up event. Repeated "virtual" keystrokes are simulated by repeating the down event without * an interveneing up event. */
public delegate void Calltype_zfb_keyEvent(int id, bool down, int windowsKeyCode);
public static Calltype_zfb_keyEvent zfb_keyEvent;
/** * Report a typed character. This typically interleaves with calls to zfb_keyEvent */
public delegate void Calltype_zfb_characterEvent(int id, int character, int windowsKeyCode);
public static Calltype_zfb_characterEvent zfb_characterEvent;
/** Register a function to call when console.log etc. is called in the browser. */
public delegate void Calltype_zfb_registerConsoleCallback(int id, ConsoleFunc callback);
public static Calltype_zfb_registerConsoleCallback zfb_registerConsoleCallback;
public delegate void Calltype_zfb_evalJS(int id, string script, string scriptURL);
public static Calltype_zfb_evalJS zfb_evalJS;
调用BrowserNative接口,唯一需要标记是browserId,这个在EmbeddedBrowser.Browser中是一个保护变量
/** Handle to the native browser. */
[NonSerialized]
internal protected int browserId;
我们给他增加一个公有属性
/** Handle to the native browser. */
[NonSerialized]
internal protected int browserId;
public int BrowserId {
get {
return browserId; } } // 增加公有属性暴露browserId
之后,我们就可以直接调用BrowserNative接口模拟鼠标输入了
public void UpdateMouseEvent(EventType eventType, ViewRect rect)
{
float x = rect.x / rect.width;
float y = rect.y / rect.height;
Vector2 pos = MapPointerToBrowser(x, y, viewRect);
if (eventType == EventType.MouseDown)
{
ZenFulcrum.EmbeddedBrowser.BrowserNative.zfb_mouseMove(browser.BrowserId, pos.x, pos.y); // 注意:x,y坐标为0-1范围
ZenFulcrum.EmbeddedBrowser.BrowserNative.zfb_mouseButton(browser.BrowserId, ZenFulcrum.EmbeddedBrowser.BrowserNative.MouseButton.MBT_LEFT, true, 1);
}
else if (eventType == EventType.MouseUp)
{
ZenFulcrum.EmbeddedBrowser.BrowserNative.zfb_mouseButton(browser.BrowserId, ZenFulcrum.EmbeddedBrowser.BrowserNative.MouseButton.MBT_LEFT, false, 1);
}
else if (eventType == EventType.MouseMove)
{
ZenFulcrum.EmbeddedBrowser.BrowserNative.zfb_mouseMove(browser.BrowserId, pos.x, pos.y); // 注意:x,y坐标为0-1范围
}
}
边栏推荐
- 【历史上的今天】7 月 3 日:人体工程学标准法案;消费电子领域先驱诞生;育碧发布 Uplay
- JSON serialization case summary
- R language uses the data function to obtain the sample datasets available in the current R environment: obtain all the sample datasets in the datasets package, obtain the datasets of all packages, and
- SSH login server sends a reminder
- Father and basketball
- MapReduce实现矩阵乘法–实现代码
- 2022-02-14 analysis of the startup and request processing process of the incluxdb cluster Coordinator
- 阿南的疑惑
- PowerPoint 教程,如何在 PowerPoint 中将演示文稿另存为视频?
- The reasons why there are so many programming languages in programming internal skills
猜你喜欢

AI scores 81 in high scores. Netizens: AI model can't avoid "internal examination"!

Seven habits of highly effective people

显卡缺货终于到头了:4000多块可得3070Ti,比原价便宜2000块拿下3090Ti

(first) the most complete way to become God of Flink SQL in history (full text 180000 words, 138 cases, 42 pictures)
![[colab] [7 methods of using external data]](/img/cf/07236c2887c781580e6f402f68608a.png)
[colab] [7 methods of using external data]
[email protected]奇安信:透视俄乌网络战 —— 网络空间基础设施面临的安全对抗与制裁博弈..."/>开始报名丨CCF C³[email protected]奇安信:透视俄乌网络战 —— 网络空间基础设施面临的安全对抗与制裁博弈...

Libuv库 - 设计概述(中文版)

Flutter动态化 | Fair 2.5.0 新版本特性

106. How to improve the readability of SAP ui5 application routing URL
![【R】 [density clustering, hierarchical clustering, expectation maximization clustering]](/img/a2/b287a5878761ee22bdbd535cae77eb.png)
【R】 [density clustering, hierarchical clustering, expectation maximization clustering]
随机推荐
物联网毕设 --(STM32f407连接云平台检测数据)
35道MySQL面试必问题图解,这样也太好理解了吧
Luogup3694 Bangbang chorus standing in line
JSP and filter
Cadre de logback
106. 如何提高 SAP UI5 应用路由 url 的可读性
MapReduce实现矩阵乘法–实现代码
Introduction to the implementation principle of rxjs observable filter operator
Can newly graduated European college students get an offer from a major Internet company in the United States?
已解决(机器学习中查看数据信息报错)AttributeError: target_names
【被动收入如何挣个一百万】
Internet of things completion -- (stm32f407 connects to cloud platform detection data)
Logseq 评测:优点、缺点、评价、学习教程
Annotation and reflection
Father and basketball
STM32 and motor development (from MCU to architecture design)
KEIL5出现中文字体乱码的解决方法
Flink SQL knows why (VIII): the wonderful way to parse Flink SQL tumble window
【历史上的今天】7 月 3 日:人体工程学标准法案;消费电子领域先驱诞生;育碧发布 Uplay
Flink SQL knows why (13): is it difficult to join streams? (next)