Unity Simple UI Manager

First of all, we need to define such a UIManager class.

public class UIManager
{

}
The UI manager, as the name implies, must be used to manage the UI in our game, and the UI in our game is generally divided into panels. So we also need a UI panel class. Then manage our UI panels through our UI manager.

public class UIPanel
{

}
Then we use the dictionary to manage our UI panels in the UI manager.

public class UIManager
{     Dictionary<string, UIPanel> panelsDic;     public UIManager()     {         panelsDic = new Dictionary<string, UIPanel>();     } } Then there are several basic attributes in our UI panel






For example, the most basic lifecycle functions, OnShow, OnHide, functions to be executed when the panel is opened and hidden. And the resource path or name of the prefab corresponding to this panel.

public abstract class UIPanel
{
    private string path;
    public string Path { get { return path; } }

    public GameObject root;

    public abstract void OnShow();

    public abstract void OnHide();

    public UIPanel(string path)
    {
        this.path = path;
    }

}
First of all, this panel class is an abstract class. Our login panel or registration panel and other UI panels need to inherit it, so this panel class itself should not be instantiated, so it is an abstract class, and then path, that is, the resource path of the prefab corresponding to the UI panel. When we open the panel through the UI manager, we need to load the panel resource according to this path and get the reference of this resource and then assign it to root, that is The root node of this prefab, and then our script can operate on this object. Then we will call the OnShow and OnHide methods when opening and hiding, and these two methods have subclasses to write specific achieved.

Then let's write UIManager next.

public class UIManager
{     Transform canvas;     Dictionary<string, UIPanel> panelsDic;     public UIManager()     {         canvas = GameObject.Find("Canvas").transform;         GameObject eventSystem = GameObject.Find("EventSystem");         GameObject.DontDestroyOnLoad(canvas );         GameObject.DontDestroyOnLoad(eventSystem);         panelsDic = new Dictionary<string, UIPanel>();     } } As I just said, we use a dictionary to store all UI panels.











Then we should also create a Canvas and EventSystem in the unity interface. These two objects, the former is the parent node of all UI panels, and the latter detects UI events, both of which must exist.

Then these two objects should also be set to not be destroyed to prevent them from being destroyed when switching scenes.

Then we should also provide the two most basic operations of opening the panel and closing the panel.

public class UIManager
{
    Transform canvas;
    Dictionary<string, UIPanel> panelsDic;
    public UIManager()
    {
        canvas = GameObject.Find("Canvas").transform;
        GameObject eventSystem = GameObject.Find("EventSystem");
        GameObject.DontDestroyOnLoad(canvas);
        GameObject.DontDestroyOnLoad(eventSystem);
        panelsDic = new Dictionary<string, UIPanel>();
    }

    public void OpenPanel<T>(T panel) where T : UIPanel
    {

    }

    public void ClosePanel<T>(T panel) where T : UIPanel
    {

    }
}
Here we provide a generic interface for closing and opening the panel, passing the panel in, but it would be too troublesome if we have to pass in the panel object every time, so we extend the panel class again.

public abstract class UIPanel
{
    private string path;
    public string Path { get { return path; } }

    public GameObject root;

    public abstract void OnShow();

    public abstract void OnHide();

    public void OpenPanel() => Singleton<UIManager>.Instance.OpenPanel(this);

    public void ClosePanel() => Singleton<UIManager>.Instance.ClosePanel(this);

    public UIPanel(string path)
    {
        this.path = path;
    }

}
Then we don't need to open or hide the panel through the UI manager at this time, but directly call the method of this object.

Next, we describe the specific implementation of these two methods.

public class UIManager
{
    Transform canvas;
    Dictionary<string, UIPanel> panelsDic;
    public UIManager()
    {
        canvas = GameObject.Find("Canvas").transform;
        GameObject eventSystem = GameObject.Find("EventSystem");
        GameObject.DontDestroyOnLoad(canvas);
        GameObject.DontDestroyOnLoad(eventSystem);
        panelsDic = new Dictionary<string, UIPanel>();
    }

    public void OpenPanel<T>(T panel) where T : UIPanel
    {
        if(panelsDic.TryGetValue(typeof(T).Name,out UIPanel oldPanel))
        {
            oldPanel.root.SetActive(true);
            oldPanel.OnShow();
        }
        else
        {
            GameObject newGO = Singleton<ResourcesManager>.Instance.Load<GameObject>(panel.Path);
            panel.root = newGO;
            panel.root.name = panel.Path;
            panel.OnShow();
            newGO.transform.SetParent(canvas);
            panelsDic.Add(typeof(T).Name,panel);
        }
    }

    public void ClosePanel<T>(T panel) where T : UIPanel
    {
        if(panelsDic.TryGetValue(typeof(T).Name,out UIPanel oldPanel))
        {
            oldPanel.root.SetActive(false);
        }
    }

}
is actually very simple. To open the panel, our implementation here is to first check whether the panel exists in the dictionary. If it exists, it will be displayed directly, and its OnShow method will be called. If it does not exist, the resource will be loaded from the resource manager. Then call his OnShow method. Closing is even simpler, judging whether it exists in the dictionary, hiding it if it exists, and hiding it if it doesn’t exist,... then there is a problem with the logic, because every time we open it, there is a Added to the dictionary, here you can catch the error. Maybe it is a misoperation.

Finally, I am posting the entire code completely, because the contents of the previous two articles are used.

public class Singleton<T> where T : new()
{
    static T instance;
    public static T Instance
    {
        get
        {
            if (instance == null)
                instance = new T();
            return instance;
        }
    }
}


public class ResourcesManager
{
    private Dictionary<string, IResource> ressDic;
    public ResourcesManager()
{
        ressDic = new Dictionary<string, IResource>();
    }

    public T Load<T>(string path) where T : UnityEngine.Object
    {
        if (ressDic.TryGetValue(path, out IResource iRes))
            return (iRes as Resource<T>).Res;
        T res = Resources.Load<T>(path);
        ressDic.Add(path, new Resource<T>(path, res));
        return res;
    }
}


public interface IResource
{

}

public class Resource<T> : IResource
{
    public Resource(string path, T res)
{
        this.path = path;
        this.res = res;
    }

    private string path;
    private T res;
    public string Path { get; }
    public T Res { get; }
}

public class UIManager
{
    Transform canvas;
    Dictionary<string, UIPanel> panelsDic;
    public UIManager()
{
        canvas = GameObject.Find("Canvas").transform;
        GameObject eventSystem = GameObject.Find("EventSystem");
        GameObject.DontDestroyOnLoad(canvas);
        GameObject.DontDestroyOnLoad(eventSystem);
        panelsDic = new Dictionary<string, UIPanel>();
    }

    public void OpenPanel<T>(T panel) where T : UIPanel
    {
        if(panelsDic.TryGetValue(typeof(T).Name,out UIPanel oldPanel))
        {
            oldPanel.root.SetActive(true);
            oldPanel.OnShow();
        }
        else
        {
            GameObject newGO = Singleton<ResourcesManager>.Instance.Load<GameObject>(panel.Path);
            panel.root = newGO;
            panel.root.name = panel.Path;
            panel.OnShow();
            newGO.transform.SetParent(canvas);
            panelsDic.Add(typeof(T).Name,panel);
        }
    }

    public void ClosePanel<T>(T panel) where T : UIPanel
    {
        if(panelsDic.TryGetValue(typeof(T).Name,out UIPanel oldPanel))
        {
            oldPanel.root.SetActive(false);
        }
    }

}

public abstract class UIPanel
{
    private string path;
    public string Path { get { return path; } }

    public GameObject root;

    public abstract void OnShow();

    public abstract void OnHide();

    public void OpenPanel() => Singleton<UIManager>.Instance.OpenPanel(this);

    public void ClosePanel() => Singleton<UIManager>.Instance.ClosePanel(this);

    public UIPanel(string path)
{
        this.path = path;
    }

}
 Author: Engine Cat https://www.bilibili.com/read/cv12007091?spm_id_from=333.999.0.0 Source: bilibili

 

Guess you like

Origin blog.csdn.net/m0_69824302/article/details/131157522