Unity C#商店菜单

时间:2019-02-11 03:52:21

标签: c# unity3d button menu

enter image description here嗨,我一直在建立一个商店菜单,当按下按钮时,该菜单就会激活。我在菜单中有四个按钮,分别与网格中的几个可购买商品相对应。按钮和文本以及附加的图像位于GameObject内部。我正在尝试使用SetActive在菜单之间切换。我已经成功地使用SetActive来打开和关闭菜单,但是当我尝试其他部分时,无论如何它们都保持不活动状态。即使按下了应该激活的按钮。我上传的图片显示了商店的层次结构。这些按钮位于ShopSelection下,而实际菜单位于UnderShop

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class UIManager : MonoBehaviour {

    private static UIManager instance;
    public  static UIManager Instance;
    public GameObject shopMenu, motherShips, resources, fleets, research;
    bool menuIsOpen = false;
    bool motherShipOpen = false;
    bool resourcesOpen = false;
    bool fleetOpen = false;
    public Button shop, motherShipButton, resourceButton, fleetButton, exitButton; 

    void Start () {
        shopMenu.SetActive(false);
        //Open Shop Menu
        Button btn = shop.GetComponent<Button>();
        btn.onClick.AddListener(TaskOnClick);
        //Open Motherships portion of shop
        Button btn1 = shop.GetComponent<Button>();
        btn1.onClick.AddListener(TaskOnClick3);
        //Open resources portion of shop
        Button btn2 = shop.GetComponent<Button>();
        btn2.onClick.AddListener(TaskOnClick4);
        //Open fleet portion of shop
        Button btn3 = shop.GetComponent<Button>();
        btn3.onClick.AddListener(TaskOnClick5);
        //Open Research portion of shop
        Button btn4 = shop.GetComponent<Button>();
        btn4.onClick.AddListener(TaskOnClick6);
        //Exit Menu
        Button bttn = exitButton.GetComponent<Button>();
        bttn.onClick.AddListener(TaskOnClick2);
    }

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

    }
    void TaskOnClick()
    {
        shopMenu.SetActive(true);
        menuIsOpen = true;
        motherShips.SetActive(true);
    }
    void TaskOnClick2()
    {
        if (menuIsOpen == true)
        {
            shopMenu.SetActive(false);
            menuIsOpen = false;
        }
    }
    void TaskOnClick3()
    {
        if(menuIsOpen == true)
        {
            //Open Motherships Shop
            motherShips.SetActive(true);
            resources.SetActive(false);
            fleets.SetActive(false);
        }
    }
    void TaskOnClick4()
    {
        if (menuIsOpen == true)
        {
            //Open resources Shop
            motherShips.SetActive(false);
            resources.SetActive(true);
            fleets.SetActive(false);
        }
    }
    void TaskOnClick5()
    {
        if(menuIsOpen == true)
        {
            //Open Fleet Shop
            motherShips.SetActive(false);
            resources.SetActive(false);
            fleets.SetActive(true);
        }
    }
    void TaskOnClick6()
    {
        if (menuIsOpen == true)
        {
            //Open Research Page
            motherShips.SetActive(false);
            resources.SetActive(false);
            fleets.SetActive(false);
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您一直将所有回调添加到shop按钮上,例如

Button btn2 = shop.GetComponent<Button>();
btn2.onClick.AddListener(TaskOnClick4);

不是假定的按钮motherShipButton, resourceButton, fleetButton


请注意,如果您将变量声明为GetComponent,则不必再次调用Button,它将自动引用Inspector中拖放的GameObject的Button组件,因此应该只是

shop.onClick.AddListener(TaskOnClick);

//Open Motherships portion of shop
motherShipButton.onClick.AddListener(TaskOnClick3);

//Open resources portion of shop
resourcesButton.onClick.AddListener(TaskOnClick4);

//Open fleet portion of shop
fleetButton.onClick.AddListener(TaskOnClick5);

//Open Research portion of shop
// Whatever button this belongs to
???.onClick.AddListener(TaskOnClick6);

//Exit Menu
exitButton.onClick.AddListener(TaskOnClick2);

现在也相应地命名方法,例如OpenMenuCloseMenu等,这将使您和其他所有人更容易理解代码。


我还怀疑您是否需要if(menuIsOpen)的支票。由于其他GameObjects仍然是菜单的子级,因此即使调用SetActive,它们也将保持不可见状态。相反,我将通过使用一种方法来确保只有一个面板处于活动状态,例如像这样的枚举

enum MenuPanel
{
    MotherShips,
    Resources,
    Fleets,
    Research
}

private void ShowPanel(MenuPanel panel)
{
    // First disable all
    motherShips.SetActive(false);
    fleets.SetActive(false);
    resources.SetActive(false);

    // Than only activate according panel
    switch(panel)
    {
        case MenuPanel.MotherShips:
            motherShips.SetActive(true);
            break;

        case MenuPanel.Reaources:
            resources.SetActive(true);
            break;

        case MenuPanel.Fleets:
            fleets.SetActive(true);
            break;
    }
}

然后,我仍然会为每个面板使用专用方法,例如

void Start()
{
    //...
    motherShipButton.onClick.AddListener(ShowMotherShips);
    //...
}

private void ShowMotherShips()
{
    ShowPanel(MenuPanel.MotherShips);
}

您也可以直接将其用作lambda表达式

void Start()
{
    //...
    motherShipButton.onClick.AddListener(() => {
        ShowPanel(MenuPanel.MotherShips);
    });
    //...
}

我通常会尽量避免使用它,因为1.您无法重用此表达式,但是您可能还想从其他地方调用它; 2.您将无法使用RemoveListener来摆脱它那个电话。