使用Raycast检测对象会被执行两次

时间:2017-01-23 02:12:52

标签: unity3d raycasting

我的场景中有两个游戏对象,我将这个脚本分配给它们。当我点击它们中的任何一个时,If语句中与每个相关的代码会被执行两次,如果我禁用其中一个,它会按原样执行一次。

void Update () 
{
    if (Input.GetMouseButtonDown(0))
    {
        RaycastHit hit;
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out hit))
        {
            if (hit.transform.name == "Object A")
            {
                Debug.Log("Object A Clicked");    // log twice
            }

            if (hit.transform.name == "Object B")
            {
                Debug.Log("Object B Clicked");   // log twice
            }
        }
    }
}

问题是,为什么代码只需单击即可执行两次?!

3 个答案:

答案 0 :(得分:1)

  

问题是,为什么代码会被执行两次for a   单击?!

因为每个帧都会调用每个脚本中的每个Update ()函数。在{strong>每个脚本的每个框架中,Input.GetMouseButtonDown(0)都会出现在更新功能中。

如果您想要检测一次,您有两个选择:

1 。仅将脚本附加到一个 GameObject。通常,一个空的GameObject。它应该在点击时用碰撞器检测任何Gamebject。

2 。使用IPointerDownHandler及其OnPointerDown功能。您可以将其附加到要检测的每个GameObject上。检查来自here#6 2d / sprites。对于3D对象,请检查#6

答案 1 :(得分:0)

这会被执行两次,因为当您点击目标时,它会执行此操作

Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

这行代码将为您提供对象,并且由于您拥有2个对象中的脚本,因此它将运行完全相同的2倍。两个对象都将重新显示相同的ray

答案 2 :(得分:0)

它记录了两次,因为当您单击鼠标左键时,两个对象都会发送光线。然后他们都使用鼠标位置从相机发送光线。然后这两条光线都会撞击和反对;

  • 如果他们点击,他们会记录相同的命中对象的名称
  • 如果他们没有打任何东西,他们就什么都不做。

可能的解决办法:

void Update () 
{
    if (Input.GetMouseButtonDown(0))
    {
        RaycastHit hit;
        Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out hit) && hit.transform == transform)
        {
            if (hit.transform.name == "Object A")
            {
                Debug.Log("Object A Clicked");    // log twice
            }

            if (hit.transform.name == "Object B")
            {
                Debug.Log("Object B Clicked");   // log twice
            }
        }
    }
}

添加" hit.transform == transform "在if条件下,您不会触发另一个对象来记录它。但是这仍然不是一个理想的解决方案,因为所有对象都会发射光线并检查光线是否会撞击它们。

更好的方法是从一个中心脚本发送光线,并让该脚本告诉对象它已被光线击中。