ugui学习 - PC键盘输入

发布时间 2023-08-01 23:48:43作者: yanghui01

最终效果

 

实现的功能

a) 点击后显示了光标, 才能输入

b) 按esc, 退出输入, 光标会隐藏

c) 输入时, 内容加在光标后面

d) Backspace删除光标后的字符

e) Delete删除光标前的字符

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class MyInputField_PCInput : MyInputField_TextSelect, IPointerClickHandler, ISelectHandler, IDeselectHandler
{
    protected string m_InputText = "";

    protected bool m_InputFocus = false;

    protected override bool IsCaretShow()
    {
        return m_InputFocus; //有输入焦点的时候才显示光标
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left)
            return;

        var go = this.gameObject;
        if (EventSystem.current.currentSelectedGameObject == go)
            OnSelect(null);
        else
            EventSystem.current.SetSelectedGameObject(gameObject, eventData);
    }

    public void OnSelect(BaseEventData eventData)
    {
        m_InputFocus = true;
        m_CaretPos = m_InputText.Length;
        m_SelectPos = m_CaretPos;
        Input.imeCompositionMode = IMECompositionMode.On;
        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); //下一帧显示光标
    }

    public void OnDeselect(BaseEventData eventData)
    {
        m_InputFocus = false;
        Input.imeCompositionMode = IMECompositionMode.Auto;
        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); //下一帧隐藏光标
    }


    private Event m_TempEvent = new Event();

    protected override void OnProcessInput()
    {
        if (!m_InputFocus) return;

        while (Event.PopEvent(m_TempEvent))
        {
            if (EventType.KeyDown == m_TempEvent.rawType)
            {
                //修饰键包括: Ctrl, Alt, Shift, Cmd, CapsLock, Numeric, 功能键
                //功能键包含: 上下左右箭头, F1~F12, Backspace, Ins, Del, Home, End, Page Up/Down, PrintScreen
                //Win, Esc, Enter, Backspace, Delete不是修饰键也不是功能键

                switch (m_TempEvent.keyCode)
                {
                case KeyCode.LeftArrow: //左移光标
                    if (m_CaretPos > 0)
                    {
                        m_CaretPos--;
                        m_SelectPos = m_CaretPos;
                        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this); //下一帧统一更新光标
                    }
                    break;
                case KeyCode.RightArrow: //右移光标
                    if (m_CaretPos < m_Text.text.Length)
                    {
                        m_CaretPos++;
                        m_SelectPos = m_CaretPos;
                        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
                    }
                    break;

                case KeyCode.Backspace: //删掉光标前面那个字符
                    if (m_InputText.Length > 0 && m_CaretPos > 0) //光标前没字符不删
                    {
                        m_InputText = m_InputText.Remove(m_CaretPos - 1, 1);
                        m_Text.text = m_InputText;
                        m_CaretPos--;
                        m_SelectPos = m_CaretPos;
                        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
                    }
                    break;
                case KeyCode.Delete: //删掉光标后面那个字符
                    if (m_InputText.Length > 0 && m_CaretPos < m_InputText.Length) //光标后没字符不删
                    {
                        m_InputText = m_InputText.Remove(m_CaretPos, 1);
                        m_Text.text = m_InputText;
                        if (m_InputText.Length > 0 && m_CaretPos > m_InputText.Length)
                        {
                            m_CaretPos = m_InputText.Length;
                            m_SelectPos = m_CaretPos;
                        }
                        CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
                    }
                    break;
                case KeyCode.Escape:
                    OnDeselect(null);
                    break;

                default:
                    if (m_TempEvent.functionKey)
                    {
                        Debug.Log($"keyCode:{m_TempEvent.keyCode}, ch:{m_TempEvent.character}");
                    }
                    else
                    {
                        char c = m_TempEvent.character; //拼音输入法时, 字符是中文
                        //Debug.Log($"ch:{c}, {(int)c}");
                        if (0 == c)
                        {
                            //按着ctrl和alt时输入, 值会为0
                            //character值为0的按键: F1~F12, Esc, CapsLock, Ctrl, Alt, Win, Cmd, 上下左右箭头, Insert, Del, Backspace, Home, End, Page Up/Down
                            //Tab键有character
                        }
                        else
                        {
                            switch (c)
                            {
                            case '\t': /* tab键 */
                                break;
                            case '\r': /* mac回车键 */
                            //case '\n': /* window回车键 */
                            case (char)3:
                                c = '\n';
                                break;
                            }

                            m_InputText = m_InputText.Insert(m_CaretPos, c.ToString());
                            m_Text.text = m_InputText;
                            m_CaretPos++;
                            m_SelectPos = m_CaretPos;
                            CanvasUpdateRegistry.RegisterCanvasElementForGraphicRebuild(this);
                        }
                    }
                    break;
                }
            }

        }
    }

}

 

InputField做了这边省略掉的:

a) 有文本选中时输入,输入内容会把选中的文本替换掉

b) 还在拼写中的中文, 会把拼音显示出来

c) ctrl+c复制, ctrl+v粘贴, ctrl+a全选, ctrl+x剪切等快捷键支持