网页嵌入插件最好的应该就是ZFBrowser了, 可是使用起来也是问题多多, 现在最要命的是网页输入不能打中文, 作者也没打算接入IME, 只能自己想办法了...
搞了半天只想到一个办法, 就是通过Unity的IME去触发中文输入, 然后传入网页, 也就是说做一个透明的 InputField 盖住网页的输入文本框, 然后在 Update 或是 onValueChanged 中把内容传给网页, 这样基本就能实现中文输入了.
因为对前端不熟悉, 我就做了一个简单网页做测试:
<html>
<head>
<title>My first page</title>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<h1>Test Input</h1>
Field1: <input type="text" id="field1">
Field2: <input type="text" id="field2">
<br>
<br>
<script>
function SetInputValue(id, str) {
document.getElementById(id).value = str;
}
function SubmitInput(str)
{
document.getElementById("field2").value = "Submited : " + str;
}
</script>
</body>
</html>
这里网页有两个Text Area, 左边作为输入, 右边作为回车后的调用测试:
然后Unity中直接用一个InputField放到 Field1 的位置上, 设置为透明, 通过Browser类提供的CallFunction方式调用就可以了:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
namespace UIModules.UITools
{
public class BrowserInputField : MonoBehaviour
{
[SerializeField]
public ZenFulcrum.EmbeddedBrowser.Browser browser;
[SerializeField]
public InputField input;
[Space(10.0f)]
[Header("设置网页 input 函数名称")]
[SerializeField]
public string SetInputFuncName = "SetInputFuncName";
[Header("设置网页 submit 函数名称")]
[SerializeField]
public string SubmitFuncName = "SubmitFuncName";
[Header("网页 input id")]
[SerializeField]
public string InputElementID = "InputElementID";
public bool inited { get; private set; }
private void Awake()
{
this.RequireComponent<CanvasGroup>().alpha = 0.01f;
Init();
}
public void Init()
{
if(input && (false == inited))
{
inited = true;
input.RequireComponent<IME_InputFollower>(); // IME 跟随
StartCoroutine(CaretAccess((_caret) =>
{
if(_caret)
{
var group = _caret.RequireComponent<CanvasGroup>();
group.alpha = 1f;
group.ignoreParentGroups = true;
}
}));
}
}
IEnumerator CaretAccess(System.Action<Transform> access)
{
if(input)
{
var caret = input.transform.Find("InputField Input Caret");
while(caret == false && input)
{
caret = input.transform.Find("InputField Input Caret");
yield return null;
}
access.Invoke(caret);
}
}
void Update()
{
if(browser && input)
{
browser.CallFunction(SetInputFuncName, new ZenFulcrum.EmbeddedBrowser.JSONNode[2]
{
new ZenFulcrum.EmbeddedBrowser.JSONNode(InputElementID),
new ZenFulcrum.EmbeddedBrowser.JSONNode(input.isFocused ? input.text : (string.IsNullOrEmpty(input.text)?input.placeholder.GetComponent<Text>().text: input.text))
});
}
}
}
}
这里InputField它会自动生成 Caret 就是输入标记, 为了让他能显示出来, 需要等待到它创建出来之后设置透明度即可. 这里省掉了IME输入法跟随的代码, 那是其它功能了.
恩, 因为字体大小不一样, 所以Caret位置不准确, 反正是能输入了.