Unity WebGL中文输入插件 支持输入法跟随 支持全屏

由于Unity WebGL本身不能很好的支持中文输入,拷贝,输入法跟随,然后网上找的插件,大多不令人满意,于是决定自己开发一个~

//2020年2月26日修改:
由于之前1.0版本的插件在Unity2019.2.4版本中打包,没有在低版本测试,导致有些使用低版本(2019以下的)的朋友无法使用,会出现missing的问题,Unity的高低版本在UI和WebGL也存在点差异,现在我重新打包一个1.1版本的插件,感谢大家的评论~

自研插件名称:ChineseInputWebGL1.1.unitypackage 插件下载

支持功能
1.中英文输入
2.支持光标移动中间插入输入
3.输入法跟随
4.支持Ctrl+C(拷贝),Ctrl+V(粘贴),Ctrl+X(裁剪)等键盘操作
5.支持WebGL全屏

主要思路:在unity WebGL打包浏览页面的对应位置,动态创建一个Html的Input控件,去实现功能

主要效果图
中文输入,输入法跟随:
Unity WebGL中文输入插件 支持输入法跟随 支持全屏_第1张图片
拷贝:
Unity WebGL中文输入插件 支持输入法跟随 支持全屏_第2张图片

主要代码
js部分:

var ChineseInputWebGL = {
	$input:null,
	$canvas:null,
	$unityContainer:null,
	$webglcontent:null,
	$unityGameObjectName : "",
	$unityInputID: "",
	$Inputing: function()
	{
		if(unityGameObjectName!=null&&unityInputID!=null && input != null)
		{
			var strvalue = unityInputID+"|"+input.value+"|"+input.selectionStart;
			SendMessage(unityGameObjectName, "OnInputText", strvalue);
		}
	},
	$InputEnd: function()
	{
		if(unityGameObjectName!=null&&unityInputID!=null && input != null)
		{
			SendMessage(unityGameObjectName,"OnInputEnd",unityInputID.toString());
		}
		document.onkeydown=null;
	},
	InputShow: function(GameObjectName_,inputID_,v_,fontsizeT_,indexStr_,inputRectStr_)
	{				
		var GameObjectName = Pointer_stringify(GameObjectName_);
		var inputID = Pointer_stringify(inputID_);
		var v = Pointer_stringify(v_);
		var fontsizeT = Pointer_stringify(fontsizeT_);
		var indexStr=Pointer_stringify(indexStr_);
		var inputRectStr = Pointer_stringify(inputRectStr_);

		var indexArr=indexStr.split("|");
		var startIndexT = indexArr[0];
		var endIndexT = indexArr[1];
		
		var inputRectArr=inputRectStr.split("|");
		var posX = inputRectArr[0];
		var posY = inputRectArr[1];
		var width = inputRectArr[2];
		var height = inputRectArr[3];

		if(input==null){
			input = document.createElement("input");
			input.type = "text";
			input.id = "ChineseInputWebGLId";
			input.name = "ChineseInputWebGL";
			input.style = "visibility:hidden;";
			input.oninput = Inputing;
			input.onblur = InputEnd;
			//document.body.appendChild(input);
			document.getElementsByClassName("webgl-content")[0].appendChild(input);//需要放在这个下面,这样就方便计算在=相对canvas下的位置
			//document.getElementById("#canvas").appendChild(input);//需要放在这个下面,这样就方便计算在=相对canvas下的位置
			input.style.pointerEvents = "none";//不遮挡鼠标事件
			//input.zIndex=1000;//设置层级使不被遮挡
		}

		if(canvas==null)
		{
			canvas = document.getElementById("#canvas");
		}
		this.screenSizeX=canvas.width;
		this.screenSizeY=canvas.height;
		
		if(unityContainer==null)
		{
			unityContainer = document.getElementById("unityContainer");
		}
		this.unityScreenSizeX=unityContainer.style.width.replace("px","");
		this.unityScreenSizeY=unityContainer.style.height.replace("px","");
		
		if(webglcontent==null)
		{
			webglcontent = document.getElementsByClassName("webgl-content")[0];
		}
		this.webglcontentSizeX=webglcontent.clientWidth;
		this.webglcontentSizeY=webglcontent.clientHeight;
		

		var offsetX=(this.screenSizeX-this.webglcontentSizeX)/2;
		var offsetY=(this.screenSizeY-this.webglcontentSizeY)/2;
		//alert(posX+"-"+this.screenSizeX+"-"+this.unityScreenSizeX+"-"+this.webglcontentSizeX+"-"+offsetX)
		//alert(posY+"-"+this.screenSizeY+"-"+this.unityScreenSizeY+"-"+this.webglcontentSizeY+"-"+offsetY)
		if(offsetX>0)
		{		
			posX=posX-offsetX;
		}
		if(offsetY>0)
		{
			posY=posY-offsetY;
		}
		
		input.style.width=width+"px";
		input.style.height=height+"px";
		input.style.left =posX+"px";//左边距
		//posY=posY-40;//测试
		input.style.top =posY+"px";//上边距
		input.value = v;
		input.style.fontSize=fontsizeT+"px";
		unityGameObjectName = GameObjectName;
		unityInputID = inputID;
		input.style.position='absolute';
		input.style.visibility = "visible";  
		input.style.opacity = 0;
		input.focus();
		input.selectionStart = startIndexT;
		input.selectionEnd  = endIndexT;
		//console.log("InputShow:"+startIndexT+"|"+endIndexT);
    
		document.onkeydown = function (event) {
			event = event || window.event; //IE suckes
			if (event.keyCode == 65 && event.ctrlKey) {//捕捉Ctrl+A事件
				SendMessage(unityGameObjectName, "SelectAll");
			}
			else if (event.keyCode == 37) {//左方向键
				var selectionindex=input.selectionStart-1;
				var strvalue = unityInputID+"|"+input.value+"|"+selectionindex;
				//console.log("左方向键:"+input.selectionStart+"|"+selectionindex);
				SendMessage(unityGameObjectName, "OnInputText", strvalue);
			}
			else if (event.keyCode == 39) {//右方向键
				var selectionindex=input.selectionStart+1;
				var strvalue = unityInputID+"|"+input.value+"|"+selectionindex;
				//console.log("右方向键:"+input.selectionStart+"|"+selectionindex);
				SendMessage(unityGameObjectName, "OnInputText", strvalue);
				
			}
		}
	}
};

C#部分:

#if UNITY_WEBGL && !UNITY_EDITOR
    int selectStartIndex;//选择文本框中文字的起始位置
    int selectEndIndex;//选择文本框中文字的结束位置
    bool isFocus;
    void Start()
    {
        inputField = GetComponent<InputField>();
        InputWebGLManage.Instance.Register(gameObject.GetInstanceID(),this);
        RectT = GetComponent<RectTransform>();
        //添加unity输入框回调
        inputField.onValueChanged.AddListener(OnValueChanged);
        inputField.onEndEdit.AddListener(OnEndEdit);
        //添加获得焦点回调
        EventTrigger trigger = inputField.gameObject.GetComponent<EventTrigger>();
        if (null == trigger)
            trigger = inputField.gameObject.AddComponent<EventTrigger>();
        EventTrigger.Entry e = new EventTrigger.Entry();
        e.eventID = EventTriggerType.PointerDown;
        e.callback.AddListener((data) => { OnFocus((PointerEventData)data); });
        trigger.triggers.Add(e);
    }

    void Update()
    {
        if (isFocus)
        {
            if (inputField.selectionAnchorPosition <= inputField.selectionFocusPosition)
            {
                if (selectStartIndex != inputField.selectionAnchorPosition || selectEndIndex != inputField.selectionFocusPosition)
                {
                    OnSelectRangeChanged(inputField.selectionAnchorPosition, inputField.selectionFocusPosition);
                }
            }
            else
            {
                if (selectStartIndex != inputField.selectionFocusPosition || selectEndIndex != inputField.selectionAnchorPosition)
                {
                    OnSelectRangeChanged(inputField.selectionFocusPosition, inputField.selectionAnchorPosition);
                }
            }
        }
    }

    #region ugui回调
    private void OnValueChanged(string arg0)
    {

    }
    private void OnFocus(PointerEventData pointerEventData)
    {
        isFocus = true;
        WebGLInput.captureAllKeyboardInput = false;
        InputShowOP(inputField.text, inputField.selectionAnchorPosition + "|" + inputField.selectionFocusPosition);
    }

    public void OnSelectRangeChanged(int startIndex, int endIndex)
    {
        selectStartIndex = startIndex;
        selectEndIndex = endIndex;
        InputShowOP(inputField.text, selectStartIndex + "|" + selectEndIndex);
    }

    public void InputShowOP(string text, string indexStr)
    {
        //获取在Canvas下的位置
        Canvas canvas = transform.GetComponentInParent<Canvas>();
        float X = 0;
        float Y = 0;
        GetPosXY(canvas, transform, ref X, ref Y);

        //左边距
        float posX = Screen.width / 2 + X - RectT.rect.width * RectT.pivot.x;
        //上边距
        float posY = Screen.height / 2 - Y - RectT.rect.height * (1 - RectT.pivot.y);

        string inputRectStr = posX + "|" + posY + "|" + RectT.rect.width + "|" + RectT.rect.height;
        string fontsize = inputField.textComponent.fontSize.ToString();
        InputWebGLManage.Instance.InputShow(gameObject.GetInstanceID().ToString(), text, fontsize, indexStr, inputRectStr);
    }

    private void OnEndEdit(string str)
    {
        isFocus = false;
    }

    /// 
    /// 获取在Canvas下的位置
    /// 
    public void GetPosXY(Canvas canvas, Transform tran, ref float x, ref float y)
    {
        x += tran.localPosition.x;
        y += tran.localPosition.y;
        if (canvas.transform == tran.parent)
        {
            return;
        }
        else
        {
            GetPosXY(canvas, tran.parent, ref x, ref y);
        }
    }

    #endregion

    #region WebGL回调
    public void OnInputText(string text,string selectIndexStr)
    {
        inputField.text = text;

        try
        {
            int selectIndex= int.Parse(selectIndexStr);
            inputField.selectionAnchorPosition = selectIndex;
            inputField.selectionFocusPosition = selectIndex;
            selectStartIndex = selectIndex;
            selectEndIndex = selectIndex;
        }
        catch
        {
            inputField.selectionAnchorPosition = inputField.text.Length;
            inputField.selectionFocusPosition = inputField.text.Length;
        }
        inputField.Select();
        inputField.ForceLabelUpdate();
    }
    public void OnInputEnd()
    {
        WebGLInput.captureAllKeyboardInput = true;
        //inputField.DeactivateInputField();
    }

    public void SelectAll()
    {
        inputField.selectionAnchorPosition = 0;
        inputField.selectionFocusPosition = inputField.text.Length;
        inputField.Select();
        inputField.ForceLabelUpdate();
    }

    #endregion
#endif

你可能感兴趣的:(Unity,WebGL)