12

查看 Unity 论坛和问答网站中的一些答案,关于如何制作不可见按钮的答案不起作用,因为移除与按钮相关的图像使其不起作用。

您如何解决这个问题并在允许按钮实际工作的同时保持不可见的属性?

4

4 回答 4

23

这是关于 Unity 的那些奇怪的事情之一......

100% 的实际项目都需要这个,但 Unity 忘记了这样做。

精简版:

在每个 Unity 项目中都需要Touchable.cs :

// file Touchable.cs
// Correctly backfills the missing Touchable concept in Unity.UI's OO chain.

using UnityEngine;
using UnityEngine.UI;
#if UNITY_EDITOR
using UnityEditor;
[CustomEditor(typeof(Touchable))]
public class Touchable_Editor : Editor
     { public override void OnInspectorGUI(){} }
#endif
public class Touchable:Text
     { protected override void Awake() { base.Awake();} }
  1. 使用 Unity普通的“创建按钮”编辑器功能

  2. 如您所知,编辑器功能会自动为您添加两个组件。一个是一个Text,一个是一个Image...

  3. 只需将它们都删除

  4. 将上面的脚本Touchable.cs 放在 Button 上

你完成了。这里的所有都是它的。

它不会随着 Unity 升级而“衰减”。

您实际上可以通过放在它上面来“扣住”任何东西.UITouchable

再也不要“添加透明图像”来制作按钮。


Unity 忘记在 OO 链中抽象一个“可触摸”的概念。

因此,我们开发人员必须“从”Unity 的类中创建我们自己的 Touchable 类。

这是 OO 中的经典“回填”问题

当“回填”时,唯一的问题是:它必须是完全自动维护的。只有一个很好的解决方案,Touchable.cs,每个人都在使用。


所以在所有现实世界的 Unity 项目中,一个按钮看起来像这样:

在此处输入图像描述

你有Unity的Button.cs

两个你必须添加Touchable.cs

一些团队制作了一个编辑器功能“创建更好的按钮”,它简单地制作了一个游戏对象,带有 Button.cs + Touchable.cs。

重要提示...

假设您可能有一个非常复杂的 UI面板。所以它会调整大小甚至有动画。

事实上,你可以把“Button+Touchable”放到任何类似的东西上,它就可以工作了。

只需设置 Button+Touchable 以便扩展以填充父级。这里的所有都是它的。

在此处输入图像描述

在这个示例图像中,“resume”和“quit”可以是任何东西。(一个动画,一个包含许多部分的复杂面板,文本,精灵,一些不可见的东西,一个堆栈 - 任何东西。)

在所有情况下,只需在下方放置一个 Button+Touchable ,您就有了一个完美无瑕的按钮。

事实上:这种方法非常简单,即使是简单的情况,您也可能会使用它。

假设您的按钮是一个微不足道的图像。只拥有一个图像,然后在其上放置一个 Button+Touchable 会容易得多。(而不是在编辑器中使用令人困惑和有问题的“按钮”功能。)

了解情况...

1) Unity 的Button.cs课程很棒。

2)但是编辑器功能“制作按钮”是垃圾......

3)它制作了一个“倒置”按钮,

4) 即,它在Button.cs下放置一个文本/图像

5)“按钮”是你应该能够添加到任何东西的东西。这正是它与 Button+Touchable 一起使用的方式。

6)所以——很简单——

1. 有你想要的。文本、图像、面板、隐形、动画——随便什么。

2. 将 Button+Touchable 放在上面 - 大功告成。

这就是每个人在 Unity 中操作所有按钮的方式!


历史信用:我相信 Unity 论坛用户“signalZak”是很多很多年前第一个想到这一点的人!

于 2016-04-27T14:27:52.083 回答
6

作为对 Fattie 答案的一种可能的改进,将Touchable的基类更改为Graphic并覆盖protected void UpdateGeometry()似乎可以很好地工作,减少与Text.

public class Touchable:Graphic
{
    protected override void UpdateGeometry() { }
}
于 2020-09-26T07:05:36.563 回答
-1

我启动了 Gimp(那个免费的编码器图形工具)。创建新图像(任何尺寸,我选择 10 pix x 10 pix),从高级(在创建对话框中)选择它的背景应该是透明的。保存了文件。将其导出为 png 并选择保存背景颜色。将其作为 sprite 拖入 Unity。把它放到按钮图形上。禁用按钮的文本组件。不需要代码......在 Gimp 中不要画任何东西(那是最难的部分)。

于 2019-09-06T07:48:23.453 回答
-1

我的第一个解决方案是如下所示的组件enabledisable

void showButton(Button buttonToShow, bool show)
{
    Image bImage = buttonToShow.GetComponent<Image>();
    Text bText = buttonToShow.GetComponentInChildren<Text>(); //Text is a child of the Button

    if (bImage != null)
    {
        bImage.enabled = show;
    }

    if (bText != null)
    {
        bText.enabled = show;
    }
}

但这没有用。如果按钮imagetext组件都是,则 不会disabled触发按钮单击事件。其中之一必须能够发送点击事件。enabled

解决方案是将imagetext组件的 alpha 设置为 0 以隐藏,设置为 1 以再次显示。它们将被隐藏但不会被禁用,并且单击events将起作用。

public Button button;

void Start()
{
    //Show Button
    showButton(button, true);

    //Hide Button
    //showButton(button, false);
}

void showButton(Button buttonToShow, bool show)
{
    Image bImage = buttonToShow.GetComponent<Image>();
    Text bText = buttonToShow.GetComponentInChildren<Text>(); //Text is a child of the Button

    if (bImage != null)
    {
        Color tempColor = bImage.color;

        if (show)
        {
            tempColor.a = 1f; //Show 
            bImage.color = tempColor;
        }
        else
        {
            tempColor.a = 0f; //Hide 
            bImage.color = tempColor;

        }
    }

    if (bText != null)
    {
        Color tempColor = bText.color;

        if (show)
        {
            tempColor.a = 1f; //Show 
            bText.color = tempColor;
        }
        else
        {
            tempColor.a = 0f; //Hide 
            bText.color = tempColor;

        }
    }
}
于 2016-04-27T12:17:25.160 回答