gpt4 book ai didi

c# - 统一按钮点击不触发事件

转载 作者:行者123 更新时间:2023-11-30 21:34:10 35 4
gpt4 key购买 nike

我看过 post located here处理相同的问题,但它既没有说明问题所在也没有解决我的问题。

我创建了一个 Canvas 预制件,面板中有许多按钮。我在运行时实例化预制件并获取面板中的所有 Button 对象。然后,我为所有调用相同 clicked() 方法的按钮的 onClick() 事件添加了一个监听器

public class GameOptions
{
private GameObject canvas;

public GameOptions(GameObject canvas)
{
this.canvas = canvas;
GameObject.Instantiate(canvas);
Text[] textObjects = canvas.GetComponentsInChildren<Text>();
Button[] buttonObjects = canvas.GetComponentsInChildren<Button>();

for (int i = 0; i < buttonObjects.Length; i++)
{
Debug.Log(buttonObjects[i].name);
buttonObjects[i].onClick.AddListener(() => clicked());
buttonObjects[i].onClick.Invoke();
}
}

public void clicked()
{
Debug.Log("Clicked!");
}
}

请注意,当我通过代码调用事件时,将调用 clicked() 并“单击!”正确输出到控制台。

但是,没有一个按钮在单击时触发事件。我还注意到检查器中 OnClick 中的 PersistentCalls.Calls 数组在运行时对所有按钮都有 0 个元素。

我在 Windows 10 64 中使用 Unity 2017.4.3f1。

最佳答案

事实上,您没有抛出任何异常,并且 onClick.Invoke() 正在触发,这表明问题是其他一些元素正在消耗点击。没有你的项目在我面前,我只能提出一些建议。

  • 确保相机和按钮之间没有任何 ui 元素(例如透明面板或图像);您可以在运行时四处移动对象,看看它们是否靠得太近并占用了点击时间。
  • 确保父 Canvas 没有将 Interactable 设置为 false 的 CanvasGroup
  • 寻找任何可能阻挡光线转换的空对象/碰撞器/监听器。

祝你好运!


编辑

在重新阅读您的代码并再次查看链接的帖子后,我发现您的代码中存在错误。

在您的 GameOptions 类构造函数中,您在收集对象时实际上并未引用实例化对象。你写了这个:

this.canvas = canvas;
GameObject.Instantiate(canvas);
Text[] textObjects = canvas.GetComponentsInChildren<Text>();

如果您查看到底发生了什么,您会将字段 canvas 分配给传递给构造函数参数的预制件。进行分配后,您使用参数实例化预制件,而不引用实例化对象。

之后,您将在 prefab 而不是实例化对象本身上调用 GetComponentsInChildren。这就是 onClick.Invoke() 被触发的原因,因为对象存在 在预制件上;它们不是您要查找的对象。

我已经重构了你的构造函数,这应该可以解决你的问题。

public GameOptions(GameObject canvas)
{
//here we instantiate the canvas item, assigning it to the field
this.canvas = GameObject.Instantiate(canvas);

//then we reference the field item, instead of the parameter item
Text[] textObjects = this.canvas.GetComponentsInChildren<Text>();
Button[] buttonObjects = this.canvas.GetComponentsInChildren<Button>();
for(int i = 0; i < buttonObjects.Length; i++)
{
Debug.Log(buttonObjects[i].name);
buttonObjects[i].onClick.AddListener(() => clicked());
buttonObjects[i].onClick.Invoke();
}
}

一些注意事项

  • 您应该使用 Canvas 项而不是 GameObject,即使您从不使用 Canvas 类的任何成员;它使以后阅读起来更容易,并防止您意外构建 new GameOptions(someRandomButton) 当您尝试访问子项时它不会做任何事情。 Canvas 对象继承自 GameObject,因此您将拥有所需的一切。
  • 您应该考虑使用不同的命名方案;这是非常主观的意见,如果你搜索 SO,就会有很多关于这个主题的争论。就我个人而言,我选择在私有(private)字段上使用下划线前缀,例如 private GameObject _canvas;,这让我毫不怀疑我没有忘记 this 因为固有的参数和字段将具有不同且唯一的命名方案。

请对我的建议持保留态度!解决问题的方法有很多种,所以最终选择最适合您的方法。

关于c# - 统一按钮点击不触发事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50573926/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com