当前位置:网站首页>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范围
}
}
边栏推荐
- The difference between stratifiedkfold (classification) and kfold (regression)
- Flick SQL knows why (10): everyone uses accumulate window to calculate cumulative indicators
- Logback 日志框架
- AI scores 81 in high scores. Netizens: AI model can't avoid "internal examination"!
- php:  The document cannot be displayed in Chinese
- 使用Tensorflow进行完整的深度神经网络CNN训练完成图片识别案例2
- Several common optimization methods matlab principle and depth analysis
- JSP and filter
- rxjs Observable filter Operator 的实现原理介绍
- [Database Principle and Application Tutorial (4th Edition | wechat Edition) Chen Zhibo] [Chapter IV exercises]
猜你喜欢

File uploading and email sending

Flink code is written like this. It's strange that the window can be triggered (bad programming habits)

MySQL installation, uninstallation, initial password setting and general commands of Linux

Internet of things completion -- (stm32f407 connects to cloud platform detection data)

Setting up remote links to MySQL on Linux

Sword finger offer 14- ii Cut rope II

rxjs Observable filter Operator 的实现原理介绍

Flink SQL knows why (XI): weight removal is not only count distinct, but also powerful duplication

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

2022-02-14 incluxdb cluster write data writetoshard parsing
随机推荐
TensorBoard可视化处理案例简析
Flink SQL knows why (XI): weight removal is not only count distinct, but also powerful duplication
[Database Principle and Application Tutorial (4th Edition | wechat Edition) Chen Zhibo] [Chapter IV exercises]
Finite State Machine FSM
Flink SQL knows why (12): is it difficult to join streams? (top)
106. 如何提高 SAP UI5 应用路由 url 的可读性
[sort] bucket sort
February 14, 2022, incluxdb survey - mind map
KEIL5出现中文字体乱码的解决方法
编程内功之编程语言众多的原因
Will Huawei be the next one to fall
Complete deep neural network CNN training with tensorflow to complete picture recognition case 2
这本数学书AI圈都在转,资深ML研究员历时7年之作,免费电子版可看
35道MySQL面试必问题图解,这样也太好理解了吧
untiy世界边缘的物体阴影闪动,靠近远点的物体阴影正常
Flink SQL knows why (VIII): the wonderful way to parse Flink SQL tumble window
MapReduce implements matrix multiplication - implementation code
Setting up remote links to MySQL on Linux
elk笔记24--用gohangout替代logstash消费日志
PowerPoint 教程,如何在 PowerPoint 中將演示文稿另存為視頻?