这个问题有很多解决方案,但似乎没有一个适合我。我有一个在UI元素中打开选择列表的按钮,我希望在它外部单击时关闭它。我目前有这个:
private void OnEnable()
{
EventSystem.current.SetSelectedGameObject(gameObject);
}
public void OnDeselect(BaseEventData eventData)
{
//Close the Window on Deselect only if a click occurred outside this panel
if (!mouseIsOver)
gameObject.SetActive(false);
}
public void OnPointerEnter(PointerEventData eventData)
{
mouseIsOver = true;
EventSystem.current.SetSelectedGameObject(gameObject);
}
public void OnPointerExit(PointerEventData eventData)
{
mouseIsOver = false;
EventSystem.current.SetSelectedGameObject(gameObject);
}
它在PC上工作得很好,但不幸的是,由于移动设备上没有实际的指针,即使在里面点击,它也会关闭面板。我试过使用这样的东西:
foreach (Touch touch in Input.touches)
{
int id = touch.fingerId;
if (EventSystem.current.IsPointerOverGameObject(id))
{
isClicked = true;
}
if (Input.GetMouseButtonDown(0))
{
// Check if the mouse was clicked over a UI element
if (EventSystem.current.IsPointerOverGameObject())
{
isClicked = true;
}
}
}
但这也没有奏效。这似乎是一个令人难以置信的简单问题,我不明白为什么我找不到一个简单的解决方案。
发布于 2020-12-08 02:57:56
我建议在创建dropdown时使用Unity技术。
看看这个link
主要的想法是在你的按钮和其他ui元素后面创建拦截器。
你的开放面板函数应该看起来像这样:
private RectTransform gameObjectTransform;
public void OpenPanel()
{
CreateBlocker();
gameObjectTransform = transform.parent;
transform.SetParent(GetComponentInParent<Canvas>());
transform.SetAsLastSibling();
}
创建拦截器方法,如文档中所示:
private GameObject currentBlocker;
public void CreateBlocker()
{
GameObject gameObject = new GameObject("Blocker");
RectTransform rectTransform = gameObject.AddComponent<RectTransform>();
rectTransform.SetParent(ChatGraphics.Instance.mainCanvas, false);
rectTransform.anchorMin = (Vector2)Vector3.zero;
rectTransform.anchorMax = (Vector2)Vector3.one;
rectTransform.sizeDelta = Vector2.zero;
Canvas canvas = gameObject.AddComponent<Canvas>();
canvas.overrideSorting = true;
canvas.sortingLayerID = component.sortingLayerID;
canvas.sortingOrder = component.sortingOrder - 1;
gameObject.AddComponent<GraphicRaycaster>();
gameObject.AddComponent<Image>().color = Color.clear;
gameObject.AddComponent<Button>().onClick.AddListener(delegate { Hide(); });
currentBlocker = gameObject;
}
最后是Hide方法,它应该在每次都被调用(即使拦截器没有触发)
public void Hide()
{
if (currentBlocker != null)
Destroy(currentBlocker);
if (gameObjectTransform != null)
transform.SetParent(gameObjectTransform);
// Your code to hide your panel
}
https://stackoverflow.com/questions/65179587
复制相似问题