Это возможно, но сложно и сложно, особенно если вы новичок в Unity.
Выполните следующие действия:
1 . Из редактора отключить interactable
в полях ввода, которые вы хотите открывать клавиатуру только при отпускании клавиши.На «Отключенный цвет» InputField, убедитесь, что изменили его на белый и альфа на полный (255), чтобы InputField не выглядел так, как будто он отключен.
Вам не нужно делать оставшиеся шаги ниже, потому что это уже сделано в скрипте в конце этого поста, но шаги ниже показывают вам, как этосделано.
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;
}
}