Есть ли способ открыть мобильную клавиатуру только при использовании полей ввода в unity3d для метода OnMouseUp ()? - PullRequest
0 голосов
/ 29 сентября 2018

Я хочу знать, есть ли способ открывать клавиатуру только после нажатия кнопки OnMouseUp (), а не метода OnMouseDown ().Я пытался изменить сценарий inputfield.cs, но он не открывается.

вот ссылка на видео

1 Ответ

0 голосов
/ 30 сентября 2018

Это возможно, но сложно и сложно, особенно если вы новичок в Unity.

Выполните следующие действия:

1 . Из редактора отключить interactable в полях ввода, которые вы хотите открывать клавиатуру только при отпускании клавиши.На «Отключенный цвет» InputField, убедитесь, что изменили его на белый и альфа на полный (255), чтобы InputField не выглядел так, как будто он отключен.

enter image description here


Вам не нужно делать оставшиеся шаги ниже, потому что это уже сделано в скрипте в конце этого поста, но шаги ниже показывают вам, как этосделано.

2 .Когда интерактивный InputField отключен, он больше не может принимать клики.При нажатии на нее не откроет клавиатуру.

Теперь вам нужно использовать GraphicRaycaster.Raycast, чтобы сделать лучевой интерфейс с ручным интерфейсом.Результат будет сохранен в List из RaycastResult.

3 .Поскольку вы хотите открывать клавиатуру только при отпускании щелчка или касания, поместите GraphicRaycaster.Raycast внутри if (Input.GetKeyUp(KeyCode.Mouse0)) для настольных устройств и if(Input.GetTouch(0).phase == TouchPhase.Ended) для мобильных устройств.Они оба вернут true в кадре при нажатии или касании.

4 .Когда щелчок отпущен с примером в # 3 , проверьте, находится ли InputField в List из RaycastResult с result.GetComponentInParent<InputField>(), если это InputField, вручную выберитеInputField с функциями SetSelectedGameObject и OnPointerClick.После этого клавиатура должна открыться на InputField, и именно тогда клавиша отпускается не при нажатии.

После этого зарегистрируйтесь на событие onEndEdit на InputField,

5 .Когда вызывается событие onEndEdit, отмените выбор InputField с помощью функции DeactivateInputField, отмените регистрацию в событии onEndEdit с помощью функции RemoveAllListeners, затем отключите или установите для интерактивного возврата значение false.


Выполните шаг # 1 только для всех InputField, которые вы хотите открывать только после нажатия кнопки или касания, затем создайте сценарий с именем "ReleaseInputOpenKeyboard", скопируйтесценарий ниже в него затем присоедините его к пустому GameObject в сцене.Мобильные клавиатуры будут отображаться на InputField только при нажатии или касании, а не при нажатии.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class ReleaseInputOpenKeyboard: MonoBehaviour
{
    GraphicRaycaster m_Raycaster;
    EventSystem m_EventSystem;

    List<GameObject> inputFieldProcessedThisFrame = new List<GameObject>();

    void Start()
    {
        m_Raycaster = GameObject.Find("Canvas").GetComponent<GraphicRaycaster>();
        //Fetch the Event System from the Scene
        m_EventSystem = FindObjectOfType<EventSystem>();
    }


    void Update()
    {
#if UNITY_STANDALONE || UNITY_EDITOR
        //DESKTOP COMPUTERS
        if (Input.GetKeyUp(KeyCode.Mouse0))
        {
            SelectInputField();
        }
#else
        if ((Input.touchCount > 0) && (Input.GetTouch(0).phase == TouchPhase.Ended))
        {
            SelectInputField();
        }
#endif
    }

    void SelectInputField()
    {
        //Set up the new Pointer Event
        PointerEventData m_PointerEventData = new PointerEventData(m_EventSystem);
        //Set the Pointer Event Position to that of the mouse position
        m_PointerEventData.position = Input.mousePosition;

        //Create a list of Raycast Results
        List<RaycastResult> results = new List<RaycastResult>();

        //Raycast using the Graphics Raycaster and mouse click position
        m_Raycaster.Raycast(m_PointerEventData, results);

        //For every result returned, output the name of the GameObject on the Canvas hit by the Ray
        foreach (RaycastResult result in results)
        {
            InputField ipf = result.gameObject.GetComponentInParent<InputField>();
            //Check if object hit is an InputField and make sure we have not processed this object this frame
            if (ipf && !inputFieldProcessedThisFrame.Contains(ipf.gameObject))
            {
                Debug.Log("Hit " + ipf.gameObject.name);

                //Mark this InputField as processed
                inputFieldProcessedThisFrame.Add(ipf.gameObject);

                //Enable interactable
                ipf.interactable = true;

                //Focus on the InputField
                ActivateInputField(ipf, m_EventSystem);

                //Add event to detect when the Input is deselected
                ipf.onEndEdit.AddListener(delegate { OnInputEnd(ipf); });
            }
        }

        //Reset processed InputField
        if (inputFieldProcessedThisFrame.Count > 0)
            inputFieldProcessedThisFrame.Clear();
    }

    void ActivateInputField(InputField ipf, EventSystem evSys)
    {
        evSys.SetSelectedGameObject(ipf.gameObject, new BaseEventData(evSys));
        ipf.OnPointerClick(new PointerEventData(evSys));
    }


    //Detects when InputField is deselected then disable interactible
    void OnInputEnd(InputField ipf)
    {
        StartCoroutine(OnInputEndCOR(ipf));
    }

    IEnumerator OnInputEndCOR(InputField ipf)
    {
        //Disable interactable then remove event
        ipf.DeactivateInputField();
        ipf.onEndEdit.RemoveAllListeners();

        /*Wait until EventSystem is no longer in selecting mode
         This prevents the "Attempting to select while already selecting an object" error
         */
        while (EventSystem.current.alreadySelecting)
            yield return null;

        ipf.interactable = false;
    }
}
...