unity3d Unity按钮点击未击发事件

093gszye  于 2023-04-12  发布在  其他
关注(0)|答案(2)|浏览(204)

我已经看过了这里的帖子,它处理了同样的问题,但它既没有说明什么是错误的,也没有解决我的问题。
我已经创建了一个面板中有许多按钮的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()被调用,并且“Clicked!”被正确地输出到控制台。
但是,当单击时,没有一个按钮会触发事件。我还注意到,Inspector中OnClick内的PersistentCalls.Calls数组在运行时对所有按钮都有0个元素。
我在Windows 10 64中使用Unity 2017.4.3f1。

g6ll5ycj

g6ll5ycj1#

你没有抛出任何异常,而onClick.Invoke()正在触发,这表明问题在于其他元素正在消耗点击量。

  • 确保相机和按钮之间没有UI元素(如透明面板或图像);您可以在运行时移动对象,以查看它们是否太近而消耗了单击。
  • 确保父画布没有Interactable设置为false的CanvasGroup
  • 查找任何可能阻挡光线投射的空对象/碰撞器/侦听器。

祝你好运!

编辑

在重新阅读你的代码,并给链接后,另一个一次通过我意识到你的代码中的一个错误。
GameOptions类构造函数中,当收集对象时,实际上并没有引用示例化的对象。您编写了以下代码:

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

如果你仔细看一下到底发生了什么,你将字段canvas赋值给传递给构造函数参数的预制件。在你赋值之后,你用参数示例化预制件,没有任何对示例化对象的引用。
之后,您将在一个 prefab 上调用GetComponentsInChildren,而不是示例化的对象本身。它们不是你要找的东西
我已经重构了你的构造函数,这应该可以解决你的问题。

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 GameObject _canvas;,这让我毫不怀疑我没有忘记this,因为本质上参数和字段都有独特的命名方案。

对我的建议持保留态度!解决问题的方法有很多很多,所以最终选择对你来说最舒服的方法。

qyswt5oh

qyswt5oh2#

只是为了帮助更多的人谁遇到这个恼人的问题。
除了EventSystemCanvas的一般配置之外,我在自己的程序中发现了另一个导致UI按钮React迟钝的原因,我认为这可能是大多数人的原因。
当你自己添加一个camera(很常见)而没有标记它时,就会出现这个问题。如果你没有标记它的线索,那么它很可能是你的原因。

要点camerastandalone input module一起使用时必须标记为MainCamera。否则它将无法识别没有碰撞器的对象。

相关问题