Unity 简单UI框架

简介:

1,通过Resources.Load加载

2,使用字典进行缓存

3,使用重载进行动静分离,创建新画布。

4,单例模式

5,核心功能:(1)打开面板 (2)关闭面板  (3)检测配置路径  (4)检测缓存

UIManager.cs

​
//框架使用说明
//在UIConst中定义要加载预制体的名字。
//在InitDicts的pathDict进行配置路径
//需要配置路径和面板名称
//在任何地方调用UIManager.Instance.OpenPanel("PanelName", true)即可
//第一个参数是面板名称,第二个参数表示是否创建一个新的动态画布用于作为面板的根节点
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class UIManager
{
    private static UIManager _instance;
    private Transform _uiRoot;
    // 路径配置字典
    private Dictionary<string, string> pathDict;
    // 预制件缓存字典
    private Dictionary<string, GameObject> prefabDict;
    // 已打开界面的缓存字典
    public Dictionary<string, BasePanel> panelDict;
    public static UIManager Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = new UIManager();
            }
            return _instance;
        }
    }

    public Transform UIRoot
    {
        get
        {
            if (_uiRoot == null)
            {
                _uiRoot = GameObject.Find("StaticCanvas").transform;
                return _uiRoot;
            };
            return _uiRoot;
        }
    }
    private UIManager()
    {
        InitDicts();
    }
    /// <summary>
    /// 初始化字典。预制体字典用于缓存,面板字典用于检测面板是否打开,路径面板用于配置路径。
    /// </summary>
    private void InitDicts()
    {
        prefabDict = new Dictionary<string, GameObject>();
        panelDict = new Dictionary<string, BasePanel>();

        pathDict = new Dictionary<string, string>()
        {
            {UIConst.Start_Panel,"Start/Start_Panel" },
            {UIConst.Start_Panel_1,"Start/Start_Panel_1" },
            {UIConst.Start_Panel_2,"Start/Start_Panel_2" },
            {UIConst.Start_Panel_3,"Start/Start_Panel_3" },
            {UIConst.Start_Panel_4,"Start/Start_Panel_4" },
            {UIConst.Start_Panel_5,"Start/Start_Panel_5" },
            {UIConst.Start_Panel_6,"Start/Start_Panel_6" },
            {UIConst.Start_Panel_7,"Start/Start_Panel_7" },
            {UIConst.Start_Panel_8,"Start/Start_Panel_8" },
            {UIConst.Start_Panel_9,"Start/Start_Panel_9" },
            {UIConst.Start_Panel_10,"Start/Start_Panel_10" },
            {UIConst.Main_Panel,"Main_Panel" },
            {UIConst.Zha_Ying_Panel,"Zha_Ying_Panel" },
            {UIConst.Troops_Panel,"Troops_Panel" },
            {UIConst.Chracter_Panel,"Chracter_Panel" },
            {UIConst.Item_Panel,"Item_Panel" },
            {UIConst.JiLu_Panel,"JiLu_Panel" },
            {UIConst.DuDang_Panel,"Start/DuDang_Panel" }

        };
    }

    /// <summary>
    /// 打开面板。第一个参数为面板名字,第二个参数是面板是否位于动态面板,如果没有则创建一个动态面板。使用字典判断该面板是否已经打开。根据配置路径找到面板,配置路径不正确,会Debug.LogError
    /// </summary>
    /// <param name="name"></param>
    /// <param name="isDynamicCanvas"></param>
    /// <returns></returns>
    public BasePanel OpenPanel(string name, bool isDynamicCanvas)
    {
        BasePanel panel = null;
        // 检查是否已打开
        if (panelDict.TryGetValue(name, out panel))
        {
            Debug.LogError("界面已打开: " + name);
            return null;
        }

        // 检查路径是否配置
        string path = "";
        if (!pathDict.TryGetValue(name, out path))
        {
            Debug.LogError("界面名称错误,或未配置路径: " + name);
            return null;
        }

        // 使用缓存预制件
        GameObject panelPrefab = null;
        if (!prefabDict.TryGetValue(name, out panelPrefab))
        {
            string realPath = "Prefab/" + path;
            //使用Resources.Load动态加载
            panelPrefab = Resources.Load<GameObject>(realPath) as GameObject;
            if (panelPrefab.GetComponent<BasePanel>() == null)
                panelPrefab.AddComponent<BasePanel>();
            prefabDict.Add(name, panelPrefab);
        }
        GameObject panelObject;
        if (isDynamicCanvas == true)
        {
            Canvas canvas;
            GameObject DynamicCanvas = GameObject.Find("DynamicCanvas");
            if (DynamicCanvas == null)
            {
                //创建动态画布画布
                GameObject canvasGo = new GameObject("DynamicCanvas");
                canvas = canvasGo.AddComponent<Canvas>();
                canvas.renderMode = RenderMode.ScreenSpaceOverlay;
                canvasGo.AddComponent<CanvasScaler>();
                canvasGo.AddComponent<GraphicRaycaster>();
                panelObject = GameObject.Instantiate(panelPrefab, canvas.transform, false);
            }
            else
            {
                panelObject = GameObject.Instantiate(panelPrefab, DynamicCanvas.transform, false);
            }
        }
        else
        {
            panelObject = GameObject.Instantiate(panelPrefab, UIRoot, false);
        }
        // 打开界面
        panel = panelObject.GetComponent<BasePanel>();
        panelDict.Add(name, panel);
        panel.OpenPanel(name);
        return panel;
    }
    /// <summary>
    /// 关闭面板。参数是面板名字。查看字典该面板没有打开就return,否则关闭该面板。
    /// </summary>
    /// <param name="name"></param>
    /// <returns></returns>
    public BasePanel OpenPanel(string name)
    {
        OpenPanel(name, false);
        return null;
    }
    public bool ClosePanel(string name)
    {
        BasePanel panel = null;
        if (!panelDict.TryGetValue(name, out panel))
        {
            Debug.LogError("界面未打开: " + name);
            return false;
        }

        panel.ClosePanel();
        //panelDict.Remove(name);不移除缓存 合适的时候移除
        return true;
    }

    public void ShowTip(string tip)
    {
        //  MenuTipPanel menuTipPanel = OpenPanel(UIConst.MenuTipPanel) as MenuTipPanel;
        //  menuTipPanel.InitTip(Globals.TipCreateOne);
    }
}
/// <summary>
/// 该结构体用于存储面板名字
/// </summary>
public struct UIConst
{
    // menu panels
    public const string Start_Panel = "Start_Panel";
    public const string Start_Panel_1 = "Start_Panel_1";
    public const string Start_Panel_2 = "Start_Panel_2";
    public const string Start_Panel_3 = "Start_Panel_3";
    public const string Start_Panel_4 = "Start_Panel_4";
    public const string Start_Panel_5 = "Start_Panel_5";
    public const string Start_Panel_6 = "Start_Panel_6";
    public const string Start_Panel_7 = "Start_Panel_7";
    public const string Start_Panel_8 = "Start_Panel_8";
    public const string Start_Panel_9 = "Start_Panel_9";
    public const string Start_Panel_10 = "Start_Panel_10";
    public const string Main_Panel = "Main_Panel";

    public const string Zha_Ying_Panel = "Zha_Ying_Panel";
    public const string Troops_Panel = "Troops_Panel";
    public const string Chracter_Panel = "Chracter_Panel";
    public const string Item_Panel = "Item_Panel";
    public const string JiLu_Panel = "JiLu_Panel";
    public const string DuDang_Panel = "DuDang_Panel";
}

​

BasePanel.cs

using UnityEngine;

public class BasePanel : MonoBehaviour
{
    protected bool isRemove = false;
    protected new string name;
    public virtual void SetActive(bool active)
    {
        gameObject.SetActive(active);
    }
    //打开面板
    public virtual void OpenPanel(string name)
    {
        this.name = name;
        SetActive(true);
    }
    //按钮事件打开面板
    public virtual void OpenNewPanel(string name)
    {
         UIManager.Instance.OpenPanel(name);
    }
    //关闭面板
    public virtual void ClosePanel()
    {
        isRemove = true;
        SetActive(false);
        Destroy(gameObject);
        if (UIManager.Instance.panelDict.ContainsKey(name))
        {
            UIManager.Instance.panelDict.Remove(name);
        }
    }
}

  • 7
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Unity中实现MVVM模式的UI系统,可以使用Unity自带的UI系统uGUI,并结合MVVM框架来实现。以下是一个简单的示例: 1. 创建一个View类,用于显示UI界面,包含需要绑定的UI元素。 ```csharp using UnityEngine; using UnityEngine.UI; public class ExampleView : MonoBehaviour { // 绑定的UI元素 public Text nameLabel; public Text descLabel; // 设置数据 public void SetData(ExampleData data) { nameLabel.text = data.name; descLabel.text = data.desc; } } ``` 2. 创建一个ViewModel类,用于处理UI界面的数据逻辑,包含需要绑定的数据属性和命令。 ```csharp using System.ComponentModel; using UnityEngine; using UnityEngine.UI; public class ExampleViewModel : INotifyPropertyChanged { // 数据属性 private string name; private string desc; public event PropertyChangedEventHandler PropertyChanged; public string Name { get { return name; } set { name = value; NotifyPropertyChanged(nameof(Name)); } } public string Desc { get { return desc; } set { desc = value; NotifyPropertyChanged(nameof(Desc)); } } // 命令 public RelayCommand SaveCommand { get; private set; } public ExampleViewModel() { // 初始化命令 SaveCommand = new RelayCommand(Save); } // 保存数据 private void Save() { // TODO: 保存数据逻辑 } // 通知属性变化 private void NotifyPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } ``` 3. 创建一个继承自MonoBehaviour的绑定类,用于将View和ViewModel进行绑定,并处理UI元素和数据属性的更新。 ```csharp using UnityEngine; using UnityEngine.UI; public class ExampleBinding : MonoBehaviour { // 绑定的View和ViewModel public ExampleView view; public ExampleViewModel viewModel; private void Start() { // 绑定ViewModel的属性和View的UI元素 view.nameLabel.text = viewModel.Name; view.descLabel.text = viewModel.Desc; // 监听ViewModel的属性变化,更新UI元素 viewModel.PropertyChanged += (sender, args) => { switch (args.PropertyName) { case nameof(ExampleViewModel.Name): view.nameLabel.text = viewModel.Name; break; case nameof(ExampleViewModel.Desc): view.descLabel.text = viewModel.Desc; break; } }; } } ``` 4. 在Unity中创建UI界面,将View和ViewModel绑定到UI元素上。 使用uGUI创建UI界面,并将ExampleView作为子对象添加到UI界面上。在ExampleBinding上将view和viewModel属性分别拖拽到uGUI上绑定的UI元素上。 5. 在代码中使用ViewModel设置数据,并触发UI更新。 ```csharp public class ExampleController : MonoBehaviour { // 绑定类 public ExampleBinding binding; private void Start() { // 设置数据 binding.viewModel.Name = "Example"; binding.viewModel.Desc = "This is an example."; // 更新UI binding.view.SetData(new ExampleData(binding.viewModel.Name, binding.viewModel.Desc)); } } ``` 以上是一个简单的在Unity中实现MVVM模式的UI系统的示例,通过绑定类将View和ViewModel进行绑定,并使用ViewModel处理UI界面的数据逻辑,实现了UI界面和数据的分离。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值