【问题标题】:How to make gameplay ignore clicks on UI Button in Unity3D?如何让游戏忽略 Unity3D 中 UI 按钮的点击?
【发布时间】:2021-10-18 16:49:41
【问题描述】:

我有一个 UI Button(使用 UnityEngine.UI)。

然而,点击Button 似乎是点击进入场景(在我的例子中点击导航网格)。

如何解决这个问题?

我一直在使用典型的 Unity3D 代码让用户参与游戏,例如

if (Input.GetMouseButtonDown(0))
  {

如果我尝试这种方法也一样

if( Input.touches.Length > 0 )
        {

        if ( Input.touches[0].phase == TouchPhase.Began )
            {

在 iOS、Android 和桌面上似乎也是如此。

点击 UI(UnityEngine.UI.Button 等)似乎是游戏中的一个基本问题。

【问题讨论】:

  • @JoeBlow 如果之前在 SO 上被问过,则将其标记为重复,否则这似乎是主题(可能对其他人有帮助的特定编程问题)

标签: c# unity3d navmesh


【解决方案1】:

以下是您今天在 Unity 中的操作方式:

  1. 您自然会在层次结构中有一个EventSystem - 只需检查您是否这样做。 (例如,当您添加 Canvas 时,您会自动获得其中一个;通常,Unity 项目中的每个场景都已经有一个 EventSystem,但只需检查您是否有一个。)

  2. 物理射线投射器添加到相机(只需单击一下)

  3. 这样做:

.

  using UnityEngine.EventSystems;
  public class Gameplay:MonoBehaviour, IPointerDownHandler {
   public void OnPointerDown(PointerEventData eventData) {
    Bingo();
    }
   }

基本上,再次基本上,就是这样。

很简单:这就是您在 Unity 中处理触摸的方式。仅此而已。

添加一个光线投射器,并拥有该代码。

看起来很简单,也很简单。但是,要做好可能会很复杂。


(脚注:在 Unity 中拖拽的一些恐惧:Horrors of OnPointerDown versus OnBeginDrag in Unity3D


Unity 的触控技术之旅令人着迷:

  1. “早期的统一”......非常容易。完全没用。根本没用。

  2. “当前的'新' Unity”......效果很好。非常简单,但很难以专业的方式使用。

  3. “即将到来的未来 Unity”......在 2025 年左右,他们将使它既能实际工作又易于使用。不要屏住呼吸。

(这种情况与 Unity 的 UI 系统没有什么不同。起初 UI 系统很可笑。现在,它很棒,但以专家的方式使用有点复杂。截至 2019 年,它们是即将再次完全改变它。)

(网络是一样的。起初它完全是垃圾。“新”网络是/曾经相当不错,但有一些非常糟糕的选择。就在最近的 2019 年,他们再次改变了网络。)


方便的相关提示!

记住!当您有一个包含一些按钮的全屏 invisible 面板时。在全屏隐形面板本身上,您必须关闭光线投射!很容易忘记:


作为一个历史问题:这里是“忽略 UI”的粗略快速修复,您曾经能够在多年前的 Unity 中使用... p>

if (Input.GetMouseButtonDown(0)) { // doesn't really work...
  if (UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
      return;
  Bingo();
  }

几年后你不能再这样做了。

【讨论】:

  • 我在发布问题之前研究了问题,但找不到任何东西。显然没有使用正确的关键字。感谢您的解决方案。发挥了魅力。
  • @Fattie - 你会这么好心并逐步描述你的解决方案,因为它最近可以实施吗?我已将physics raycaster 添加到相机,但 OnClick 按钮事件仍会传播到游戏/场景...
  • 天啊,有 5 亿篇文章说要使用 EventSystem.current.IsPointerOverGameObject,这让我无处可去,但这非常有效!谢谢!
  • 嗨@Min - 对,Unity 的一个大问题是存在大量过时 文章。这很棘手。还要注意,他们现在正在引入另一个“全新”的 UX 系统:/ WTH 对吗?
【解决方案2】:

我也遇到了这个问题,我找不到非常有用的信息,这对我有用:

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

public class SomeClickableObject : MonoBehaviour
{
    // keep reference to UI to detect for
    // for me this was a panel with some buttons
    public GameObject ui;

    void OnMouseDown()
    {
        if (!this.IsPointerOverUIObject())
        {
            // do normal OnMouseDown stuff
        }
    }

    private bool IsPointerOverUIObject()
    {
        // get current pointer position and raycast it
        PointerEventData eventDataCurrentPosition = new PointerEventData(EventSystem.current);
        eventDataCurrentPosition.position = new Vector2(Input.mousePosition.x, Input.mousePosition.y);
        List<RaycastResult> results = new List<RaycastResult>();
        EventSystem.current.RaycastAll(eventDataCurrentPosition, results);

        // check if the target is in the UI
        foreach (RaycastResult r in results) {
            bool isUIClick = r.gameObject.transform.IsChildOf(this.ui.transform); 
            if (isUIClick) {
                return true;
            }
        }
        return false;
    }
}

基本上每次点击都会检查点击是否发生在 UI 目标上。

【讨论】:

  • 再次执行 UI 系统自己执行的相同光线投射的一种 hack,但据我所知,没有更好的方法让 EventSystem 告诉你是否它自己的光线投射击中了某些东西。
【解决方案3】:

不幸的是,第一个建议对我没有帮助,所以我只使用了五个所有面板标签“UIPanel”,并在单击鼠标时检查当前是否有任何面板处于活动状态

    void Update()
    { if (Input.GetMouseButtonDown(0))
        {
            if (isPanelsOn()) 
            {}//doing nothing because panels is on
            else 
            {} //doing what we need to do
         }
}
public static bool isPanelsOn()
    {
        GameObject[] panels = GameObject.FindGameObjectsWithTag("UIPanel");
        foreach (var panel in panels)
        {
           if (panel.activeSelf)
            {
                return true; 
            }
        }
        return false;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多