嗨,我一直在建立一个商店菜单,当按下按钮时,该菜单就会激活。我在菜单中有四个按钮,分别与网格中的几个可购买商品相对应。按钮和文本以及附加的图像位于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);
}
}
}
答案 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);
现在也相应地命名方法,例如OpenMenu
,CloseMenu
等,这将使您和其他所有人更容易理解代码。
我还怀疑您是否需要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
来摆脱它那个电话。