当前位置: 首页 > news >正文

【Unity UGUI 交互组件——Dropdown(TMP版本)(10)】

下拉菜单在游戏或者应用中都有很多应用,比如背包中的分类,语言设置等等。Unity UGUI提供了Dropdown组件来实现这个功能。参考官方手册

1.介绍

一张运行展开下拉菜单图如下,默认状态是收起状态,没有DropdownList(DropdownList运行时动态生成的​​临时性交互界面​​,它在用户点击下拉框时被创建,在选择完成后自动销毁)。
组件层级结构 。在Hierarchy 中新建 UI ▸ Dropdown-TextMeshPro 时,Unity 会自动生成 4 个必备节点:

  1. Dropdown-TextMeshPro(根节点,挂有下拉逻辑脚本 TMP_Dropdown)
  2. Label(TextMeshPro-UGUI,显示当前选中的文字)
  3. Arrow(Image,右侧小三角)
  4. Template(整个下拉列表模板,内含滚动区域、Viewport、Content 以及 Item 模板)

在这里插入图片描述

对象中文名作用
Dropdown (根)下拉根节点Dropdown 脚本
Label标题文本显示当前选中文字(对应 Caption Text)
Arrow展开箭头指示点击区域,旋转 180° 表示展开/收起
Template列表模板非激活,展开时克隆为下拉列表
Item (在 Template 内)列表项模板Toggle + Item Text / Item Image
DropdownList (展开状态下自动生成)下拉项列表运行时动态生成的​​临时性交互界面​​,它在用户点击下拉框时被创建,在选择完成后自动销毁。

2.组成

(1).Dropdown

在这里插入图片描述

一、Dropdown(TMP)参数

以下按在上图参数出现顺序列出常用字段,并给出用途说明。

  1. Interactable / Transition / Navigation
    与 Button、Toggle 等标准 UI 控件的交互状态完全一致,不再赘述。

  2. Template
    关联第 4 个节点 RectTransform。运行时列表展开时会把 Template 的副本实例化并显示。Template 里必须包含:
    • ScrollRect(滚动区域)
    • Content(Vertical Layout Group + Content Size Fitter,用于动态排列 Item)
    • Item(Item 模板,挂有 Toggle + Layout Element)

  3. Caption Text
    指向 Label 上的 TextMeshPro-UGUI 组件,用于显示当前选项文本。

  4. Caption Image
    如果想在文字前面再显示一个小图标(如国旗),可把 Image 拖进来,运行时会把当前选项对应的 Sprite 赋值给它。

  5. Item Text
    指向 Item 模板里的 TextMeshPro-UGUI,用于渲染列表中每一行的文字。

  6. Item Image
    同理,对应每一行的图标 Image。

  7. Value
    当前选中项的索引(int)。-1 表示未选中任何项,此时 Caption Text 会显示 Placeholder 文字。

  8. Options(List)
    在 Inspector 中可逐条添加下拉选项。每条 OptionData 包含:
    • text(string)
    • image(Sprite,可为空)

  9. Placeholder
    当 Value == -1 时,Label 会显示此占位符文字;常用于“请选择…”提示。

  10. Multi-select
    勾选后允许用户通过 Ctrl/Shift 多选;目前需自行在代码里读取 selectedIndices 数组。

  11. On Value Changed(Int32)
    标准 UnityEvent,当选中索引发生变化时触发。可拖脚本,也可运行时 AddListener。

二、常用拓展与脚本控制

  1. 动态增删选项
var dropdown = GetComponent<TMP_Dropdown>();
dropdown.options.Add(new TMP_Dropdown.OptionData("新选项"));
dropdown.RefreshShownValue();
  1. 显示/隐藏图标
dropdown.captionImage.sprite = mySprite;
dropdown.itemImage.sprite = mySprite;
  1. 监听事件
dropdown.onValueChanged.AddListener(index => Debug.Log($"选了第 {index} 项"));
  1. 样式与特效
    由于文本已替换成 TextMeshPro-UGUI,可直接在 Label/Item 上加材质参数(Outline、Shadow、Glow 等),或利用富文本标签 <sprite=0> 等实现彩色图文混排。

  2. 性能与滚动
    Template 里的 ScrollRect 拥有 Scroll Sensitivity 字段,可调整滚轮速度;若选项极多,可把 Content 上的 Vertical Layout Group + Content Size Fitter 换成更轻量的 Layout Group 或对象池方案。

(2).Laber

Label是下拉框用来显示“当前选中项文字”的专用 TextMeshPro-UGUI 节点,位于层级结构的第二层级(Dropdown-TextMeshPro ▸ Label)。它既受 TMP_Dropdown 逻辑驱动,也拥有完整的 TextMeshPro-UGUI 能力。Hierarchy 中新建 UI ▸ Dropdown-TextMeshPro 时,Unity 会同步生成 1 个 Label 节点。

在这里插入图片描述

(3).Arrow

Arrow(Dropdown-TextMeshPro 中的下拉箭头) 是位于 Caption 区域最右侧的视觉指示器,用来告诉用户“这里可以点开下拉列表”。它本质上是一个 Image 控件,挂靠在 Dropdown-TextMeshPro 的第三层级,仅做显示与过渡效果,不参与文本逻辑。细心的小伙伴可能已经看出来,这个Arrow只有RT和Image组件,并没有类似Button一样的组件,实际上他是通过射线检测的。(感兴趣点击查看原理)
在这里插入图片描述

性能这一块
• 箭头仅 1 个 Image,顶点数极低,无需对象池。
• 若使用 Addressable 图标,确保 Sprite Atlas 打包,避免额外 DrawCall。
• 在移动平台,箭头尺寸建议 ≥ 44×44 pt(苹果 HIG 最小触控区域),避免误触。

(4).Template

Template(下拉列表模板)是 Dropdown-TextMeshPro 的模板,负责在运行时把一份预先搭好的 UI 结构克隆出来,变成玩家真正能看到、能滚动的下拉列表。它平时处于 禁用状态,只有在点击下拉框时才被 实例化并激活。
在这里插入图片描述


一、它为什么会出现(设计目的)

  1. 一次性预制
    下拉列表通常包含 N 个 Item,Item 数量在运行时可能动态变化。如果把所有元素都直接放在场景里,每次增删都得实时创建/销毁,成本高。
  2. 统一样式
    通过模板,可以保证所有下拉框的外观、布局、动画完全一致,只需改一份 Template 即可全局生效。
  3. 惰性实例化
    Template 默认是 Inactive 的,不占用渲染、布局、更新开销;点击后才 Instantiate,用完 Destroy

二、Template 本身是什么

  • 一个普通的 GameObject,挂有 RectTransform。
  • 不挂载任何逻辑脚本(逻辑全部由 TMP_Dropdown 在 Show() 里接管)。
  • Scene 可见性:Inspector 里默认是灰色(未激活),运行时会被克隆为 Dropdown List(名字固定)。
  • 引用方式:TMP_Dropdown 组件的 Template 字段拖拽关联该物体;缺失会抛出 MissingReferenceException

三、Template 的标准组成(层级关系 )

Template (RectTransform)
├─ Viewport (RectTransform + Mask 或 RectMask2D + GraphicRaycaster*)
│  ├─ Content (RectTransform + Vertical Layout Group + Content Size Fitter)
│  │  ├─ Item (Toggle + Layout Element + Image + TextMeshPro-UGUI)
│  │  ├─ Item (Clone …)
│  │  └─ …
│  └─ Scrollbar (可选,Scrollbar 组件)
└─ Canvas (可选,仅当需要独立 Canvas 时)

注:带 * 的组件由 TMP_Dropdown 在运行时动态附加,模板本身不需要提前挂。


四、每个子物体的职责与关键参数

子物体必须/可选关键组件 & 常用设置作用说明
Template必须RectTransform模板根节点,决定整个下拉列表的锚点、尺寸;TMP_Dropdown 会把它作为克隆源。
Viewport必须Mask / RectMask2D + Image把超出边缘的 Item 裁剪掉;Image 用来接收射线(点击空白处自动关闭下拉)。
Content必须Vertical Layout Group + Content Size Fitter垂直排列 Item;Content Size Fitter 的 Preferred Size 让高度随 Item 数量动态增长。
Item必须Toggle + Layout Element单条选项的可交互单元;Toggle 的 onValueChanged 由 TMP_Dropdown 统一接管。
└─ Item Background内部Image背景图,支持不同状态(Normal / Highlighted / Pressed)。
└─ Item Checkmark内部Image当前选中项的对勾图标,仅在被选中时激活。
└─ Item Label内部TextMeshPro-UGUI显示文字,对应 OptionData.text。
Scrollbar可选Scrollbar + Image + Mask当 Item 过多时出现;可替换成 ScrollRect 的 horizontal / verticalScrollbar

五、运行时的极简时序图

用户点击 Dropdown → TMP_Dropdown.Show()1. clone = Instantiate(Template)2. clone.name = "Dropdown List"3. clone.SetActive(true)4. clone.AddComponent<Canvas>(); clone.AddComponent<GraphicRaycaster>();5. 填充 Content 的子物体:根据 options.Count 复制 Item6. 绑定事件:点击 Item → 修改 dropdown.value → 关闭列表
用户再次点击或选择 → TMP_Dropdown.Hide()1. Destroy(clone)

一句话总结
Template 就是 Dropdown 的「蓝图」。

(4).Dropdown List

在这里插入图片描述

Dropdown List(运行时展开的下拉列表) 是 Template 的克隆体,在玩家点击下拉框的瞬间由 TMP_Dropdown 动态生成、填充并摆到屏幕最上层。它只在 Show() → Hide() 之间存活,生命周期极短,却是用户真正能看到、能滚动、能点选的完整 UI。


一、出现目的(为什么要克隆出它)

  1. 隔离运行时数据
    Template 只是“蓝图”——保持编辑状态不变;克隆体可随意增删 Item、改 Rect、加动画而不影响原模板。
  2. 独立渲染层级
    下拉列表需要覆盖在其他 UI 之上,因此运行时会给克隆体额外挂一个 Canvas + GraphicRaycaster,并把 sortingOrder 调高(默认 30000)。
  3. 用完即毁
    用户选中或点击外部后立刻 Destroy 避免常驻内存和更新开销。

二、Dropdown List 本身是什么

  • 名字固定:运行时实例化后统一命名为 “Dropdown List”(可在层级视图动态看到)。
  • 根节点:一个 RectTransform 组件,完全复制 Template 的锚点、尺寸、Pivot。
  • 激活开关SetActive(true) 时才可见;关闭后 SetActive(false) 或直接销毁。
  • 脚本不挂任何自定义脚本,所有逻辑仍由 TMP_Dropdown 持有并驱动。

三、标准组成(层级 & 组件)

Dropdown List (RectTransform)
├─ Viewport (RectTransform + Mask/RectMask2D + GraphicRaycaster*)
│  ├─ Content (RectTransform + Vertical Layout Group + Content Size Fitter)
│  │  ├─ Item (Toggle + Layout Element + Image + TextMeshPro-UGUI)
│  │  ├─ Item (Clone …)
│  │  └─ … (根据 options.Count 动态克隆)
│  └─ Scrollbar (Vertical) (可选)
└─ Canvas* + GraphicRaycaster*   ← 运行时由 TMP_Dropdown 自动添加

带 * 的组件在 Template 里 不存在,是运行时 额外加 的。


四、每个子物体的运行时职责 & 参数

子物体运行时来源关键组件 & 常用设置作用说明
Dropdown ListInstantiate(Template)RectTransform + Canvas + GraphicRaycaster根节点;Canvas 负责独立排序,GraphicRaycaster 负责接收射线。
Viewport克隆自 Template.ViewportMask / RectMask2D把超出边缘的 Item 裁剪掉;Image 背景同时作为“点击空白关闭”的检测区域。
Content克隆自 Template.ContentVertical Layout Group + Content Size Fitter垂直排列 Item;Content Size Fitter 的 PreferredSize 让高度随 Item 数量动态增长。
Item(N 条)克隆自 Template.ItemToggle + Layout Element + Image + TextMeshPro-UGUI单条可交互选项;Toggle.group 由 TMP_Dropdown 自动管理,保证单选。
└─ Item Background克隆Image背景图;支持不同状态(Normal / Highlighted / Pressed)。
└─ Item Checkmark克隆Image对勾图标;仅当前选中项显示。
└─ Item Label克隆TextMeshPro-UGUI显示文字,自动绑定 OptionData.text。
Scrollbar克隆自 Template.Scrollbar(可选)Scrollbar + Image + Mask当 Item 数量超出 Viewport 高度时出现;与 ScrollRect 联动。

五、生命周期 & 关键代码片段

// TMP_Dropdown.Show() 精简流程
GameObject list = Instantiate(template.gameObject);
list.name = "Dropdown List";
list.SetActive(true);// 1. 额外挂 Canvas 与 GraphicRaycaster
Canvas c = list.AddComponent<Canvas>();
c.overrideSorting = true;
c.sortingOrder = 30000;
list.AddComponent<GraphicRaycaster>();// 2. 填充 Content
RectTransform content = list.transform.Find("Viewport/Content") as RectTransform;
foreach (var option in options)
{GameObject item = Instantiate(itemTemplate, content);item.GetComponentInChildren<TMP_Text>().text = option.text;item.GetComponent<Toggle>().onValueChanged.AddListener(OnItemValueChanged);
}// 3. 点击空白关闭
list.GetComponentInChildren<MaskableGraphic>().AddComponent<CloseOnOutsideClick>();

总结
Dropdown List 就是 Template 的“副本”:只在需要时出生,带着独立 Canvas、排好 Item、等用户点选;任务完成立即销毁。


文章转载自:

http://xiWBjbAc.mqffm.cn
http://s3xdUr35.mqffm.cn
http://hYlC1Ddj.mqffm.cn
http://W6EB3Rl5.mqffm.cn
http://DGNtVHmF.mqffm.cn
http://cBd5paRh.mqffm.cn
http://4iBv3ueS.mqffm.cn
http://1KWqwwMa.mqffm.cn
http://mRIcHKFU.mqffm.cn
http://KoFezMzM.mqffm.cn
http://fVLBXiUq.mqffm.cn
http://gvZUueaP.mqffm.cn
http://mMrLV5VN.mqffm.cn
http://CAArLmB4.mqffm.cn
http://whyTomgt.mqffm.cn
http://hFWymHXV.mqffm.cn
http://Uq2EGemY.mqffm.cn
http://YsHfEqZV.mqffm.cn
http://PmSUZHhF.mqffm.cn
http://1kIByhM5.mqffm.cn
http://TmzLCVTI.mqffm.cn
http://gguj9bus.mqffm.cn
http://EE9gLJJf.mqffm.cn
http://RJB2LWv2.mqffm.cn
http://LjhalZXX.mqffm.cn
http://MXHHRJvs.mqffm.cn
http://IUZbCAg1.mqffm.cn
http://bqNbxtZC.mqffm.cn
http://j60EuP5M.mqffm.cn
http://n6nygOiZ.mqffm.cn
http://www.dtcms.com/a/378208.html

相关文章:

  • 自动化拨号爬虫体系:虚拟机集群部署与增量管理
  • 【机器人运动学】正运动学分析
  • 基于机器学习的P2P网贷平台信用违约预测模型
  • 工厂怎么认证iso14067
  • flutter项目 -- 换logo、名称 、签名、打包
  • 【Windows】VMware安装Ubuntu操作系统
  • 仿函数的分析与应用
  • 框架漏洞详解
  • Day02 集合 | 30. 串联所有单词的子串、146. LRU 缓存、811. 子域名访问计数
  • 基于springboot的教育资源共享管理系统
  • 汽车网络安全 CyberSecurity ISO/SAE 21434 测试之一
  • Fiddler
  • 【软件设计师(中级)】P1 计算机系统知识(待完成)
  • KronosTokenizer结构解析
  • (网络编程)网络编程套接字 UDP的socket API 代码解析
  • iPhone17系列发布!跨端如何破局?
  • 把nginx、jar包、redis做成windows系统服务,开机自动启动
  • Java学习笔记四(继承)
  • Redis分布式锁的try-with-resources实现
  • 广东省省考备考(第九十七天9.11)——言语(刷题巩固第三节课)
  • ReentrantLock 源码深度解析
  • 机器人驭风而行:低空经济如何开启智能新纪元
  • 【系统架构设计(27)】信息安全技术集成
  • spring mvc 拦截器 (HandlerInterceptor )
  • 【Nginx】- 日志定期清理设置
  • 102、23种设计模式之装饰器模式(11/23)
  • SwiftData3 一剑封喉:WWDC25 的“数据剑谱”精讲,让 Core Data 老侠原地退休
  • [硬件电路-180]:集成运放,在同向放大和反向放大电路中,失调电压与信号一起被等比例放大;但在跨阻运放中,失调电压不会与电流信号等比例放大。
  • IDEA连接redis数据库时出现Failed to connect to any host resolved for DNS name.
  • kafka:【2】工作原理