如何让游戏玩法忽略Unity3D中UI按钮的点击?

Pet*_*ter 9 c# unity-game-engine navmesh

我正在尝试创建一个3D点击以在Unity3D中移动游戏.

我添加了一个UI Button(使用UnityEngine.UI),我想最终点击以打开和关闭运行.

然而,点击Button实际上似乎是点击进入场景(在我的情况下UnityEngine.UI.Button导航)并导致我的播放器移动到不同的位置.

如何禁用光线投射以单击UI按钮或以某种方式让UI捕获自己的事件?

我一直在使用典型的Unity3D代码让用户进入游戏玩法等

if (Input.GetMouseButtonDown(0))
  {
Run Code Online (Sandbox Code Playgroud)

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

if( Input.touches.Length > 0 )
        {

        if ( Input.touches[0].phase == TouchPhase.Began )
            {
Run Code Online (Sandbox Code Playgroud)

在iOS,Android和桌面上似乎就是这种情况.

这似乎是一个基本问题,点击UI(Button等)似乎落入游戏玩法.

Fat*_*tie 21

关于这个非常古老的问题:

作为一个历史问题:这里是粗略的准备好的快速修复,你以前几年前在Unity中可以使用它...

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

实际上,几年来你不能再这样做了.


抛开历史性的快速解决方案......

以下是您今天在Unity中的表现:

  1. 添加一个raycaster(只需点击一下),然后

  2. 做这个:

-

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

基本上,基本上,这就是它的全部内容.

很简单:这就是你在Unity中处理触摸的方式.这里的所有都是它的.

添加一个raycaster,并拥有该代码.

它看起来很简单,而且很容易.但是,做得好可能很复杂.


(脚注1 - 完整细节:Unity3D中OnPointerDown与OnBeginDrag的恐怖)

(脚注2 - 由于历史原因:如果链接仍然有效,这里是关于如何在Unity中进行"新"触摸的原始着名视频,从那时起:链接,第3部分.)


Unity通过触摸技术的旅程非常吸引人:

  1. "早期团结"......非常容易.完全没用.根本没用.

  2. "当前的'新'统一'......工作得很漂亮.很容易,但很难以专家的方式使用.

  3. "即将到来的Unity"......大约在2025年,他们将实际工作并且易于使用.不要屏住呼吸.

(情况与Unity的UI系统没有什么不同.起初,UI系统是可笑的.现在,它很棒,但以专家的方式使用有点复杂.)


方便的相关提示!

记得!当你有一个全屏隐形面板,其中包含一些按钮.在全屏隐形面板上,您必须关闭光线投射!很容易忘记:

在此输入图像描述


小智 5

我也遇到了这个问题,但我找不到太多有用的信息,这对我有用:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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