(想要实现的功能是:在一个主Canvas下有多个面板,通过点击某一个面板下的按钮切换到另外一个面板,再通过点击这个面板下的按钮切换到上一个面板,或者其他的面板,也就是在多个面板间进行自由的切换,简单的来说就是对UI进行管理,实现各个UI 间的自由切和交互)
首先,写一个PanelInstance.cs类,为每个要管理的panel添加这个脚本,PanelInstance.cs的代码示例如下:(PanelInstance.cs)//面板类
using UnityEngine;
using System.Collections;
public class PanelInstance : MonoBehaviour
{
public PanelInstance PanelBefore;
}
然后写一个管理Panel的类,这里称作PanelManager,PanelManager.cs的代码如下所示:(PanelManager.cs)
using UnityEngine;
using System.Collections;
using System;
public class PanelManager : MonoBehaviour {
public PanelInstance[] Pages;
public PanelInstance currentPanel;
void Start()
{
for(int i = 0; i < Pages.Length; i++)
{
Pages[i].gameObject.AddComponent<PanelInstance>();
}
}
void Awake()
{
if (Pages.Length <= 0)
{
return;
}
OpenPanel(Pages[0]);
}
//打开面板
public void OpenPanel(PanelInstance page)
{
if (page == null)
{
return;
}
page.PanelBefore = currentPanel;
currentPanel = page;
CloseAllPanels();
Animator anim = page.GetComponent<Animator>();
if (anim && anim.isActiveAndEnabled)
{
anim.SetBool("Open", true);
}
page.gameObject.SetActive(true);
Debug.Log("面板"+page.gameObject.name+"已经打开");
}
//通过名字打开面板
public void OpenPanelByName(string name)
{
PanelInstance page = null;
for (int i = 0; i < Pages.Length; i++)
{
if (Pages[i].name == name)
{
page = Pages[i];
break;
}
}
if (page == null)
{
return;
}
page.PanelBefore = currentPanel;
currentPanel = page;
CloseAllPanels();
Animator anim = page.GetComponent<Animator>();
if (anim && anim.isActiveAndEnabled)
{
anim.SetBool("Open", true);
}
page.gameObject.SetActive(true);
}
//关闭所有面板
public void CloseAllPanels()
{
if (Pages.Length <= 0)
{
return;
}
for(int i = 0; i < Pages.Length; i++)
{
Animator anim = Pages[i].gameObject.GetComponent<Animator>();
if (anim && anim.isActiveAndEnabled)
{
anim.SetBool("Open", false);
}
if (Pages[i].isActiveAndEnabled)
{
StartCoroutine(DisablePanelDeleyed(Pages[i]));
}
}
}
//禁用面板
public IEnumerator DisablePanelDeleyed(PanelInstance page)
{
bool closedStateReached = false;
bool wantToClose = true;
Animator anim = page.gameObject.GetComponent<Animator>();
if (anim && anim.enabled)
{
while (!closedStateReached && wantToClose)
{
if (anim.isActiveAndEnabled && !anim.IsInTransition(0))
{
closedStateReached = anim.GetCurrentAnimatorStateInfo(0).IsName("Closing");
}
yield return new WaitForEndOfFrame();
}
if (wantToClose)
{
anim.gameObject.SetActive(false);
}
}
else
{
page.gameObject.SetActive(false);
}
}
}
最后在主Canvas画布上添加一个MainMenuManager,这里称之为MainMenuManager.sc,代码如下:
(MainMenuManager.cs)//主画布管理类
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
//注意此处,MainMenuManager是继承自PanelManager的
public class MainMenuManager:PanelManager {
public string SceneStart = "zombieland";
public Text CharacterName;
public GameObject Preloader;
void Start()
{
}
public void ExitGame()
{
Application.Quit();
}
public void OpenPreviousPanel()
{
if (currentPanel && currentPanel.PanelBefore)
{
CloseAllPanels();
Animator anim = currentPanel.PanelBefore.GetComponent<Animator>();
if (anim && anim.isActiveAndEnabled)
{
anim.SetBool("Open", true);
}
currentPanel.PanelBefore.gameObject.SetActive(true);
currentPanel = currentPanel.PanelBefore;
}
}
}
然后在Unity中的Canvas的MainMenuManager.cs中把想要参与管理和切换的面板添加到数组Pages中,再为每个按钮添加相应的点击函数事件(包括点击这个按钮跳转到另外一个Panel,并执行某个功能),这样,就可以实现通过点击按钮切换到想要显示的面板,并执行相应的功能;这个类对于只需在少于5个面板直接的切换来说有点太过于复杂了,对于管理10个以上的面板切换是非常有用的,只需要根据面板的名字来进行切换就行了
再提供一个思路,在管理类中申明一个变量保存当前被打开的面板。当切换面板时,将切换的面板的变量值赋予管理类中声明的变量。