检测 2D Collider 是否正在从 Unity 2D 中的其他脚本中触摸鼠标指针

Detecting if 2D Collider is touching Mouse Pointer from Other script in Unity 2D

我正在使用 Unity2D 开发一个项目,目标是能够参考其他主要脚本以从中获取信息。在这种特定情况下,我需要从单独的脚本中检测鼠标指针是否正在接触对撞机。

通常,我可以创建一个布尔值,并在鼠标悬停时将其设置为 true,在鼠标退出时将其设置为 false,如下所示:

bool isHovered;

void OnMouseEnter() {
    isHovered = true;
}

void OnMouseExit() {
    isHovered = false;
}

但是,在脚本中,我不想为每个单独的脚本执行此操作,而是想引用另一个脚本,如下所示:

public GameManager g;

void Update() {
    if (g.IsTouchingMouse(gameObject)) { //Code }
}

但这有很多问题。在我的游戏管理器 class 中,我需要这样的东西

public bool IsTouchingMouse(gameObject g) { return value }

这有多个问题,因为我没有办法在另一个脚本上为这些对象注册 OnMouseEnter 和 OnMouseExit 事件,我也没有办法为每个对象存储值gameObject 以确保这适用于每个对象,而无需手动修改此脚本。

我正在寻找两件事,#1,我如何检测鼠标悬停在脚本中的对象上,而脚本的父对象不是那个 gameObject,第二,关于如何创建函数以 return这个变量立即?

有点烦人,但我在发帖几分钟后找到了解决方案。所以我就在这里分享一下。

public bool IsTouchingMouse(GameObject g)
{
    Vector2 point = Camera.main.ScreenToWorldPoint(Input.mousePosition);
    return g.GetComponent<Collider2D>().OverlapPoint(point);
}

这段代码基本上是在做一个函数,将游戏对象作为输入,根据鼠标光标在世界中的位置创建一个 vector2 space,然后 returns无论天气与否,对象包含的 2D 碰撞器实际上正在接触这个假想点,变量“点”应该可以与任何 2D 世界 space 位置互换。我几乎把整个问题复杂化了。

找到两个你喜欢的资源导入到Unity的Assets中,设置Texture Type为Cursor

创建一个新脚本并将其挂载到一个空对象。 打开脚本,创建三个public类型Texture2D的变量,return到Unity,然后将你喜欢的指针贴图拖到变量window.

设置对象标签,我们通过自定义标签判断改变哪个指针;所以首先为对象设置标签。比如地面,我给它加了Ground标签,墙加了Wall标签;该列添加了 Cylinder 标记。

写一个改变鼠标指针的方法,其中改变指针的主要API是Cursor.SetCursor()

      void setCursorTexture()
      {
          Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);//Define the ray pointed by the mouse in the game window
          RaycastHit hitInfo; //Information of ray collision
          if (Physics.Raycast(ray, out hitInfo))//Determine whether to hit the object
         {
            // switch pointer
            switch (hitInfo.collider.gameObject.tag)
           {
             case "Ground":
                 Cursor.SetCursor(groundCr, new Vector2(16, 16), CursorMode.Auto);
                 break;
             case "Wall":
                 Cursor.SetCursor(wallCr, new Vector2(16, 16), CursorMode.Auto);
                 break;
             case "Cylinder":
                 Cursor.SetCursor(CylinderCr, new Vector2(16, 16), CursorMode.Auto);
                 break;
             default:
                 Cursor.SetCursor(null,Vector2.zero,CursorMode.Auto);
                 break;
              }
          }
       }

在每帧调用的 Update() 方法中实现此方法。

END(可以去运行程序)谢谢,希望能帮到你

这个方法无一例外地有效。要解决此问题,请尝试以下方法:

public Collider2D collider; // target Collider

void Update()
{
    var mouseRay = Camera.main.ScreenPointToRay(Input.mousePosition);
    
    if (collider.bounds.IntersectRay(mouseRay)) Debug.Log("Mouse on collider..");
}

对于新的输入系统?

但是Input.mousePosition在Unity中给出了一个新的系统错误。解决这个问题,如下图调用鼠标位置:

var mousePos = Mouse.current.position.ReadValue();

您还可以检查 if (new input system enabled) 是否处于活动状态,如下所示:

#if ENABLE_INPUT_SYSTEM
    var mousePos = Mouse.current.position.ReadValue();
#else
    var mousePos = Input.mousePosition;
#endif

然后跟随相机光线的方向:

var mouseRay = Camera.main.ScreenPointToRay(mousePos);