赞
踩
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全屏导致坐标映射错误、窗口不在前台、干扰正常鼠操作等等问题,使用非常不友好。
查看源代码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范围 } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。