网页嵌入插件最好的应该就是ZFBrowser了, 可是使用起来也是问题多多, 现在最要命的是网页输入不能打中文, 作者也没打算接入IME, 只能自己想办法了...
搞了半天只想到一个办法, 就是通过Unity的IME去触发中文输入, 然后传入网页, 也就是说做一个透明的 InputField 盖住网页的输入文本框, 然后在 Update 或是 onValueChanged 中把内容传给网页, 这样基本就能实现中文输入了.
因为对前端不熟悉, 我就做了一个简单网页做测试:
1<html> 2 3<head> 4 <title>My first page</title> 5 <style> 6 body { 7 margin: 0; 8 } 9 </style> 10</head> 11 12<body> 13 <h1>Test Input</h1> 14 Field1: <input type="text" id="field1"> 15 Field2: <input type="text" id="field2"> 16 <br> 17 <br> 18 <script> 19 function SetInputValue(id, str) { 20 document.getElementById(id).value = str; 21 } 22 function SubmitInput(str) 23 { 24 document.getElementById("field2").value = "Submited : " + str; 25 } 26 </script> 27 28</body> 29 30</html>
这里网页有两个Text Area, 左边作为输入, 右边作为回车后的调用测试:

然后Unity中直接用一个InputField放到 Field1 的位置上, 设置为透明, 通过Browser类提供的CallFunction方式调用就可以了:
1using System.Collections; 2using System.Collections.Generic; 3using UnityEngine; 4using UnityEngine.UI; 5using UnityEngine.EventSystems; 6 7namespace UIModules.UITools 8{ 9 public class BrowserInputField : MonoBehaviour 10 { 11 [SerializeField] 12 public ZenFulcrum.EmbeddedBrowser.Browser browser; 13 [SerializeField] 14 public InputField input; 15 16 [Space(10.0f)] 17 [Header("设置网页 input 函数名称")] 18 [SerializeField] 19 public string SetInputFuncName = "SetInputFuncName"; 20 [Header("设置网页 submit 函数名称")] 21 [SerializeField] 22 public string SubmitFuncName = "SubmitFuncName"; 23 [Header("网页 input id")] 24 [SerializeField] 25 public string InputElementID = "InputElementID"; 26 27 public bool inited { get; private set; } 28 29 private void Awake() 30 { 31 this.RequireComponent<CanvasGroup>().alpha = 0.01f; 32 Init(); 33 } 34 35 public void Init() 36 { 37 if(input && (false == inited)) 38 { 39 inited = true; 40 input.RequireComponent<IME_InputFollower>(); // IME 跟随 41 42 StartCoroutine(CaretAccess((_caret) => 43 { 44 if(_caret) 45 { 46 var group = _caret.RequireComponent<CanvasGroup>(); 47 group.alpha = 1f; 48 group.ignoreParentGroups = true; 49 } 50 })); 51 } 52 } 53 54 IEnumerator CaretAccess(System.Action<Transform> access) 55 { 56 if(input) 57 { 58 var caret = input.transform.Find("InputField Input Caret"); 59 while(caret == false && input) 60 { 61 caret = input.transform.Find("InputField Input Caret"); 62 yield return null; 63 } 64 access.Invoke(caret); 65 } 66 } 67 68 void Update() 69 { 70 if(browser && input) 71 { 72 browser.CallFunction(SetInputFuncName, new ZenFulcrum.EmbeddedBrowser.JSONNode[2] 73 { 74 new ZenFulcrum.EmbeddedBrowser.JSONNode(InputElementID), 75 new ZenFulcrum.EmbeddedBrowser.JSONNode(input.isFocused ? input.text : (string.IsNullOrEmpty(input.text)?input.placeholder.GetComponent<Text>().text: input.text)) 76 }); 77 } 78 } 79 } 80}
这里InputField它会自动生成 Caret 就是输入标记, 为了让他能显示出来, 需要等待到它创建出来之后设置透明度即可. 这里省掉了IME输入法跟随的代码, 那是其它功能了.

恩, 因为字体大小不一样, 所以Caret位置不准确, 反正是能输入了.