使用 Raycast 检测对象会执行两次
Detecting objects using Raycast gets executed twice
我的场景中有两个游戏对象,我将此脚本分配给它们。当我单击它们中的任何一个时,与每个相关的 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
}
}
}
}
问题是,为什么单击一次代码会执行两次?!
The question is, why does the code gets executed twice with for a
single click?!
因为每个脚本中的每个 Update ()
函数在每一帧都会被调用。 Input.GetMouseButtonDown(0)
将在 每个 脚本中的每个帧中都为真,在更新函数中包含它。
如果你想让它检测一次,你有两个选择:
1。仅将脚本附加到 one GameObject。通常是一个空的游戏对象。单击时,它应该会检测到任何带有碰撞器的游戏对象。
2。使用 IPointerDownHandler
及其 OnPointerDown
函数。您可以将其附加到您想要检测点击的每个游戏对象。检查 #6 来自 的 2d/sprites。对于 3D 对象,选中 #6.
这会执行两次,因为当您点击一个目标时,它会执行此操作
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
那行代码,会给你这个对象,因为你有 2 个对象中的脚本,它会 运行 2 次完全相同的东西。两个对象将收到相同的 ray
.
记录了两次,因为当您单击鼠标左键时,两个对象都会发送光线。然后他们都使用鼠标位置从相机发送光线。那么这两条射线命中与否;
- 如果他们命中,他们会记录相同的命中对象的名称
- 万一他们没有撞到任何东西,他们什么都不做。
可能的修复:
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
}
}
}
}
通过在 if 条件中添加“hit.transform == transform”,您不会触发其他对象记录它。但这仍然不是一个理想的解决方案,因为您的所有对象都会发送光线并检查光线是否击中了它们。
更好的方法是从一个中央脚本发送射线,然后让该脚本告诉对象它已被射线击中。
我的场景中有两个游戏对象,我将此脚本分配给它们。当我单击它们中的任何一个时,与每个相关的 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
}
}
}
}
问题是,为什么单击一次代码会执行两次?!
The question is, why does the code gets executed twice with for a single click?!
因为每个脚本中的每个 Update ()
函数在每一帧都会被调用。 Input.GetMouseButtonDown(0)
将在 每个 脚本中的每个帧中都为真,在更新函数中包含它。
如果你想让它检测一次,你有两个选择:
1。仅将脚本附加到 one GameObject。通常是一个空的游戏对象。单击时,它应该会检测到任何带有碰撞器的游戏对象。
2。使用 IPointerDownHandler
及其 OnPointerDown
函数。您可以将其附加到您想要检测点击的每个游戏对象。检查 #6 来自
这会执行两次,因为当您点击一个目标时,它会执行此操作
Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
那行代码,会给你这个对象,因为你有 2 个对象中的脚本,它会 运行 2 次完全相同的东西。两个对象将收到相同的 ray
.
记录了两次,因为当您单击鼠标左键时,两个对象都会发送光线。然后他们都使用鼠标位置从相机发送光线。那么这两条射线命中与否;
- 如果他们命中,他们会记录相同的命中对象的名称
- 万一他们没有撞到任何东西,他们什么都不做。
可能的修复:
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
}
}
}
}
通过在 if 条件中添加“hit.transform == transform”,您不会触发其他对象记录它。但这仍然不是一个理想的解决方案,因为您的所有对象都会发送光线并检查光线是否击中了它们。
更好的方法是从一个中央脚本发送射线,然后让该脚本告诉对象它已被射线击中。