在 OnMouseUp() 方法上使用 unity 3d 中的输入字段时,有没有办法只打开移动键盘?
Is there way to only open the mobile keyboard when using inputfields in unity3d on the OnMouseUp() method?
我想知道是否有一种方法只能在单击 OnMouseUp() 而不是 OnMouseDown() 方法后打开键盘。我尝试修改 inputfield.cs 脚本,但它打不开。
这是可能的,但非常棘手和复杂,尤其是当刚接触 Unity 时。
执行以下操作:
1。 从编辑器 禁用您希望仅在释放键时打开键盘的 InputFields 上的 interactable
。在 InputField 的 "Disabled Color" 上,确保将其更改为白色并将 alpha 更改为完整 (255),这样 InputField 就不会看起来像是被禁用了。
您不必执行下面的剩余步骤,因为它已经在本post末尾的脚本中完成,但下面的步骤向您展示了如何完成。
2。当禁用 InputField
interactable 时,它不能再接受点击。单击它不会 打开键盘。
您现在必须使用 GraphicRaycaster.Raycast
to do a manual UI raycast. The result will be stored in a List
of RaycastResult
。
3。由于您只想在释放点击或触摸时打开键盘,因此将 GraphicRaycaster.Raycast
放在桌面设备的 if (Input.GetKeyUp(KeyCode.Mouse0))
和移动设备的 if(Input.GetTouch(0).phase == TouchPhase.Ended)
中。当点击或触摸被释放时,它们都会 return true
在框架上。
4。 #3中的例子释放点击时,检查InputField
是否在RaycastResult
和result.GetComponentInParent<InputField>()
的List
中,如果它是一个 InputField
,手动 select InputField
与 SetSelectedGameObject
和 OnPointerClick
函数。在此之后,键盘应该在 InputField
上打开,那是在释放键而不是按下时。
之后,在 InputField
上注册 onEndEdit
事件。
5。当调用onEndEdit
事件时,使用DeactivateInputField
函数取消selectInputField
,使用[=35=从onEndEdit
事件中注销] 函数然后禁用或将可交互设置回 false
.
仅对所有 InputField
执行步骤 #1,您只想在释放单击或触摸时打开键盘,然后创建一个名为“ReleaseInputOpenKeyboard
",将下面的脚本复制到其中,然后将其附加到场景中的空游戏对象。移动键盘只会在点击或触摸被释放而不是被按下时显示在 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;
}
}
我想知道是否有一种方法只能在单击 OnMouseUp() 而不是 OnMouseDown() 方法后打开键盘。我尝试修改 inputfield.cs 脚本,但它打不开。
这是可能的,但非常棘手和复杂,尤其是当刚接触 Unity 时。
执行以下操作:
1。 从编辑器 禁用您希望仅在释放键时打开键盘的 InputFields 上的 interactable
。在 InputField 的 "Disabled Color" 上,确保将其更改为白色并将 alpha 更改为完整 (255),这样 InputField 就不会看起来像是被禁用了。
您不必执行下面的剩余步骤,因为它已经在本post末尾的脚本中完成,但下面的步骤向您展示了如何完成。
2。当禁用 InputField
interactable 时,它不能再接受点击。单击它不会 打开键盘。
您现在必须使用 GraphicRaycaster.Raycast
to do a manual UI raycast. The result will be stored in a List
of RaycastResult
。
3。由于您只想在释放点击或触摸时打开键盘,因此将 GraphicRaycaster.Raycast
放在桌面设备的 if (Input.GetKeyUp(KeyCode.Mouse0))
和移动设备的 if(Input.GetTouch(0).phase == TouchPhase.Ended)
中。当点击或触摸被释放时,它们都会 return true
在框架上。
4。 #3中的例子释放点击时,检查InputField
是否在RaycastResult
和result.GetComponentInParent<InputField>()
的List
中,如果它是一个 InputField
,手动 select InputField
与 SetSelectedGameObject
和 OnPointerClick
函数。在此之后,键盘应该在 InputField
上打开,那是在释放键而不是按下时。
之后,在 InputField
上注册 onEndEdit
事件。
5。当调用onEndEdit
事件时,使用DeactivateInputField
函数取消selectInputField
,使用[=35=从onEndEdit
事件中注销] 函数然后禁用或将可交互设置回 false
.
仅对所有 InputField
执行步骤 #1,您只想在释放单击或触摸时打开键盘,然后创建一个名为“ReleaseInputOpenKeyboard
",将下面的脚本复制到其中,然后将其附加到场景中的空游戏对象。移动键盘只会在点击或触摸被释放而不是被按下时显示在 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;
}
}