Unity WebGL中文輸入插件 支持輸入法跟隨 支持全屏

由於Unity WebGL本身不能很好的支持中文輸入,拷貝,輸入法跟隨,然後網上找的插件,大多不令人滿意,於是決定自己開發一個~

自研插件名稱:ChineseInputWebGL0.unitypackage 插件下載

支持功能
1.中英文輸入
2.支持光標移動中間插入輸入
3.輸入法跟隨
4.支持Ctrl+C(拷貝),Ctrl+V(粘貼),Ctrl+X(裁剪)等鍵盤操作
5.支持WebGL全屏

主要思路:在unity WebGL打包瀏覽頁面的對應位置,動態創建一個Html的Input控件,去實現功能

主要效果圖
中文輸入,輸入法跟隨:
在這裏插入圖片描述
拷貝:
在這裏插入圖片描述

主要代碼
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;
    }

    /// <summary>
    /// 獲取在Canvas下的位置
    /// </summary>
    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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章