在Unity中,如何不使用UI来创建按钮?

6
有没有一种在Unity中创建简单的2D按钮而不使用UI层的方法。我有一个有很多按钮的游戏,我不想将整个应用程序制作成UI。欢迎添加更多控件:开关、滑块等。
PS.我看到了NGUI,但到目前为止我不喜欢它。还有其他选择吗?

2DToolkit完美地实现了这一点,它内置了所有的功能。(在许多方面,2DTK仍然非常有用:我们永远不会做任何2D项目而没有它。)NGUI不是一个解决方案。或者你可以像程序员在下面完美地解释的那样自己创建。但我不得不想 - 为什么不直接使用Unity的UI呢?问题出在哪里? - Fattie
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Programmer
也许是我的问题,但是在2D游戏中使用Unity UI按钮对我来说看起来很奇怪。我无法将其放入对象层次结构中,它的比例与我的精灵不同,我无法将其附加到特定的排序图层等等。所以我有点迷失了。 - Maxim Lavrov
1
你是对的。你不能把它放在对象层次结构中。UI必须在Canvas GameObject下面。这很好,因为你的UI应该与你的游戏对象分离。同样的事情也适用于你的UI代码。它应该与你的游戏逻辑分开,以便于易于故障排除和可移植性。这不应该是什么问题。你是否有任何想要做的UI操作,由于对象层次结构而无法实现? - Programmer
此外,您可以更改Canvas的排序层。对于Canvas下的UI组件的排序层,它们从上到下渲染。如果有任何问题,您可以重新排列它们。 - Programmer
1
@MaximLavrov 你可以将画布设置为游戏对象的子对象。请参考Unity官网上坦克教程中的坦克生命值视频 - Scott Chamberlain
2个回答

4
在Unity中,您可以使用 Sprite/Sprite Render 作为 Button。首先创建一个游戏对象,并将 EventSystemStandaloneInputModule 添加到它上面。将 Physics2DRaycaster 添加到相机上,实现 IPointerClickHandler 并重写 OnPointerClick 函数。通过前往GameObject->2D Object->Sprite 创建 2D 精灵,然后将脚本附加到精灵上。以下是完成此操作的完整代码:
using UnityEngine;
using UnityEngine.EventSystems;
using System.Collections;

public class SPRITEBUTTON: MonoBehaviour, IPointerClickHandler,
                                  IPointerDownHandler, IPointerEnterHandler,
                                  IPointerUpHandler, IPointerExitHandler
{

    void Start()
    {
        //Attach Physics2DRaycaster to the Camera
        Camera.main.gameObject.AddComponent<Physics2DRaycaster>();

        addEventSystem();
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        Debug.Log("Mouse Clicked!");
    }

    public void OnPointerDown(PointerEventData eventData)
    {
        Debug.Log("Mouse Down!");
    }

    public void OnPointerEnter(PointerEventData eventData)
    {
        Debug.Log("Mouse Enter!");
    }

    public void OnPointerUp(PointerEventData eventData)
    {
        Debug.Log("Mouse Up!");
    }
    public void OnPointerExit(PointerEventData eventData)
    {
        Debug.Log("Mouse Exit!");
    }

    //Add Event System to the Camera
    void addEventSystem()
    {
        GameObject eventSystem = null;
        GameObject tempObj = GameObject.Find("EventSystem");
        if (tempObj == null)
        {
            eventSystem = new GameObject("EventSystem");
            eventSystem.AddComponent<EventSystem>();
            eventSystem.AddComponent<StandaloneInputModule>();
        }
        else
        {
            if ((tempObj.GetComponent<EventSystem>()) == null)
            {
                tempObj.AddComponent<EventSystem>();
            }

            if ((tempObj.GetComponent<StandaloneInputModule>()) == null)
            {
                tempObj.AddComponent<StandaloneInputModule>();
            }
        }
    }

}

编辑:

如果这是一个3D游戏对象/网格,则需要向其添加一个简单的碰撞器。如果它只是一个精灵,则必须向该精灵添加2D碰撞器。


您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Maxim Lavrov
1
Raycast 不会检测没有碰撞器的游戏对象。我以为你已经知道了。 - Programmer
对于像我这样的新手来说,一切都是新的。我甚至不知道什么是 Raycast :) 对我来说,现在它只是一种魔法。我相信把它加入答案中对其他新手会更好。 - Maxim Lavrov
刚刚更新了问题。如果你是Unity新手,那么你应该关注这个链接http://unity3d.com/learn/tutorials 它对于新手来说有很多好东西。 - Programmer
哇,这真是太不可思议了。完美地运作着。感谢您的帮助。 - hiroki

4

另一种更简单的方法是只需添加一个BoxCollider2D组件,然后将以下方法添加到新组件(例如UIButton)中,以执行按钮操作:

  1. void OnMouseOver()
  2. void OnMouseDown()
  3. void OnMouseUp()

这样就避免了使用EventSystem、StandaloneInputModule和Physics2DRaycaster。

示例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class UIButton : MonoBehaviour {

    public Sprite regular;
    public Sprite mouseOver;
    public Sprite mouseClicked;
    public TextMeshPro buttonText;

    // Use this for initialization
    void Start () {

    }

    // Update is called once per frame
    void Update () {

    }

    private void OnMouseDown()
    {

    }

    private void OnMouseEnter()
    {

    }

    private void OnMouseExit()
    {

    }

    private void OnMouseUpAsButton()
    {

    }
}

此代码在Unity 2018.1中进行了测试。与上述方法相比,我最初注意到的一个区别是,在此模型中无法检测到鼠标右键单击事件,但可以在EventSystemModel中检测到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接