Unity 3D 笔记(十)简易 UI 管理框架、JSON 配置解析、反射动态创建界面、栈结构界面层级管理

发布时间:2026/7/21 7:06:14

Unity 3D 笔记(十)简易 UI 管理框架、JSON 配置解析、反射动态创建界面、栈结构界面层级管理 本篇核心知识点原生硬编码 UI 缺陷、JSON 配置文件语法、Unity JsonUtility 序列化反序列化、枚举转换字符串、反射动态挂载界面脚本、单例 UI 管理器、字典缓存界面、栈管理弹窗层级、面向对象架构优化一、原生直接写 UI 的缺陷无框架对比1 概念不使用管理框架每个按钮单独写加载逻辑、硬编码资源路径界面全部写死新增 / 删除界面需要大量修改代码维护成本极高。2 特性 / 规则每个按钮单独写Resources.Load界面数量上百时代码冗余严重资源路径写死字符串拼写错误运行才报错编译无提示无法统一管理界面生命周期打开、隐藏、销毁新增界面需要新增按钮监听、新增加载代码扩展性极差多个界面同时弹出无法做层级控制弹窗会互相遮挡错乱。3 语法 代码片段原生硬编码反面示例// 不推荐每个按钮单独写加载硬编码路径 public void OpenTaskPanel(){ GameObject taskPrefab Resources.LoadGameObject(UI/TaskPanel); Instantiate(taskPrefab, canvas.transform); } public void OpenBagPanel(){ GameObject bagPrefab Resources.LoadGameObject(UI/BagPanel); Instantiate(bagPrefab, canvas.transform); }4 相关知识点对比原生硬编码 VS 框架统一管理原生硬编码上手简单界面一多代码爆炸维护困难UI 框架通过配置表统一管理路径新增界面仅修改 JSON代码无需改动易维护、可扩展。5 模块拓展企业项目标准大型游戏界面几十上百个必须使用配置 管理器架构禁止硬编码路径。二、JSON 配置文件基础语法1 概念JSON 是键值对文本配置文件存储界面名称、资源路径统一管理所有 UI 预制体地址程序运行一次性读取替代分散硬编码路径。2 特性 / 规则基础结构数组包裹多条对象每条对象用{}键值key:value逗号分隔数组使用[]包裹最后一条数据不能加逗号否则解析报错字符串必须双引号包裹数字 / 布尔无需引号线上 JSON 校验工具可快速排查语法逗号、引号错误。3 语法 代码片段UI 配置 JSON 示例[ { panelName: MainPanel, resPath: UI/MainPanel }, { panelName: TaskPanel, resPath: UI/TaskPanel }, { panelName: BagPanel } ]4 相关知识点对比JSON VS TXT/ExcelJSONUnity 原生JsonUtility直接解析键值对应类属性开发首选Xmile?Excel需要第三方插件转数据打包复杂TXT无标准键值格式手动分割字符串易出错。5 模块拓展Json 在线校验格式配置文件规范资源路径统一分类存放UI、角色、道具分不同 JSON 文件避免单文件过大。三、Unity JsonUtility 序列化与反序列化1 概念Unity 内置 JSON 解析工具FromJson将文本转程序对象反序列化ToJson将对象导出文本序列化类添加[System.Serializable]标签才能参与解析。2 特性 / 规则序列化标签[System.Serializable]必须添加否则无法映射 JSON 字段类字段名称必须和 JSON 键名完全一致大小写、拼写不能错分层解析外层总数组类→单条面板数据类逐层读取字符串与枚举可互转解决字符串路径写错无编译提示问题。3 语法 代码片段using System; [Serializable] public class UIPanelData{ public string panelName; public string resPath; } [Serializable] public class UIConfigRoot{ public ListUIPanelData panelList; } ​ // 读取并反序列化JSON TextAsset jsonText Resources.LoadTextAsset(Config/UIConfig); UIConfigRoot config JsonUtility.FromJsonUIConfigRoot(jsonText.text);4 相关知识点对比序列化 VS 反序列化反序列化FromJson文件文本 → 程序类对象项目读取配置用序列化ToJson程序数据 → JSON 文本存档、导出数据使用。5 模块拓展解析后用DictionaryPanelType, string存储枚举做 Key 替代字符串规避拼写 Bug。四、枚举管理界面类型规避字符串错误1 概念自定义枚举区分所有界面替代原始字符串标识编译阶段就能检测拼写错误无需运行报错。2 特性 / 规则JSON 存储界面名字符串解析后自动转枚举枚举与类字段互相转换使用Enum.Parse完成字符串转枚举字典 Key 使用枚举代码输入时有代码提示减少低级错误。3 语法 代码片段// 界面枚举定义 public enum PanelType{ MainPanel, TaskPanel, BagPanel } // 字符串转枚举 UIPanelData data; PanelType type (PanelType)Enum.Parse(typeof(PanelType), data.panelName);4 相关知识点对比字符串标识 VS 枚举标识字符串无代码提示拼写错误运行才崩溃枚举编译器校验IDE 自动提示大型项目强制使用。5 模块拓展新增界面仅新增枚举项、JSON 加一行配置无需修改任何加载逻辑。五、反射动态创建界面脚本1 概念通过 C# 反射机制根据界面名字符串自动查找对应脚本类动态AddComponent挂载不需要大量if/switch判断分支。2 特性 / 规则界面脚本类名和 JSON 内 panelName 保持完全一致反射获取Type调用AddComponent(Type)动态挂载先判断物体是否已有该脚本防止重复挂载彻底消除大量分支判断新增界面不用修改管理器代码。3 语法 代码片段// 通过名字获取脚本类型 Type panelType Type.GetType(UI. panelName); // 避免重复挂载 if(panelObj.GetComponent(panelType) null){ panelObj.AddComponent(panelType); }4 相关知识点对比Switch 分支挂载 VS 反射动态挂载Switch每新增界面新增分支代码冗长难维护反射统一一行代码自动匹配无限拓展界面。5 模块拓展反射性能说明界面仅打开时执行一次几乎无性能损耗项目完全可用。六、UI 管理器单例架构设计1 概念单例UIManager全局唯一管理类负责读取配置、缓存界面预制、打开 / 关闭面板、统一画布管理全局任意脚本调用UIManager.Instance操作 UI。2 特性 / 规则单例模式保证全局只有一个管理器实例两个核心字典DictionaryPanelType, string枚举→资源路径缓存配置DictionaryPanelType, BasePanel枚举→已实例化界面脚本缓存实例不重复创建所有界面继承BasePanel基类统一提供 Show/Hide 通用方法游戏启动一次性加载 JSON 配置全程无需重复读取文件。3 语法 代码片段// 单例模板 public class UIManager : MonoBehaviour{ public static UIManager Instance { get; private set; } void Awake(){ if(Instance ! null Instance ! this) Destroy(gameObject); else Instance this; } // 打开面板核心方法 public void OpenPanel(Panel type){ if(panelDict.TryGetValue(type, out BasePanel panel)){ panel.Show(); return; } // 无实例加载预制、实例化、反射挂载、存入字典 } } // 基类所有界面继承 public class BasePanel : MonoBehaviour{ public virtual void Show() gameObject.SetActive(true); public virtual void Hide() gameObject.SetActive(false); }4 相关知识点对比全局散 UI 逻辑 VS 单例管理器散逻辑各处加载界面路径混乱、无法统一缓存单例管理器统一入口统一缓存、统一生命周期管理。5 模块拓展基类拓展添加 OnOpen、OnClose 回调界面打开关闭自动执行自定义逻辑。七、栈结构管理弹窗层级1 概念利用栈先进后出数据结构管理弹窗后打开界面永远在栈顶最上层点击上层弹窗关闭后自动显示上一层界面解决多弹窗遮挡错乱问题。2 特性 / 规则栈StackBasePanel存储打开的界面打开新界面 Push 入栈关闭界面 Pop 出栈栈顶界面永远激活显示下层界面可隐藏背包详情弹窗、设置弹窗多层共存场景必备。3 语法 代码片段private StackBasePanel panelStack new StackBasePanel(); // 打开弹窗 public void PushPanel(BasePanel panel) if(panelStack.Count 0) panelStack.Peek().Hide(); panelStack.Push(panel); panel.Show(); } // 关闭顶层弹窗 public void PopPanel(){ if(panelStack.Count 0) return; BasePanel top panelStack.Pop(); top.Hide(); if(panelStack.Count 0) panelStack.Peek().Show(); }4 相关知识点对比直接叠加界面 VS 栈层级管理直接叠加多层弹窗互相遮挡关闭后底层无法自动恢复栈结构自动维护层级关闭顶层自动显示前一个界面。5 模块拓展大型游戏弹窗系统标准实现商城、背包、活动多弹窗场景必用。综合拓展1 UI 框架完整开发流程搭建 BasePanel 基类→编写 JSON 配置→创建枚举→管理器单例→反序列化解析配置→反射动态挂载界面→栈实现弹窗层级。2 性能优化规范游戏启动一次性读取 JSON运行不重复加载资源文本实例化界面存入字典缓存避免重复 Instantiate界面隐藏而非销毁复用减少 GC反射仅界面创建执行运行无频繁反射消耗3 高频 Bug 排查清单JSON 解析失败检查字段名、末尾逗号、序列化标签反射找不到脚本类名和 panelName 不一致枚举转换报错JSON 字符串和枚举名拼写错误弹窗层级错乱未使用栈结构管理界面。4 面试核心考点JSON序列化反序列化原理、反射动态创建对象、单例实现、栈数据结构 UI 弹窗管理、配置表替代硬编码优势。5 项目拓展落地将见缝插针、登录背包旧项目重构为这套 UI 架构写入简历体现工程化、面向对象开发能力。

相关新闻