Unity 改写Dropdown支持多次点击同一选项均回调
1.UGUI自带的Dropdown,创建之后,运行场景默认选择第一个选项,再次点击第一个选项也不会触发,因项目需求,所以要改成多次点击有效
2.创建下拉框(Dropdown),创建好之后删除Dropdown组件
3.创建c#脚本 (重写下拉框,添加一个bool变量用来控制)
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class DropdownEx : Dropdown { public bool m_AlwaysCallback = false; public void ShowController() { base.Show(); Transform toggleRoot = transform.Find("Dropdown List/Viewport/Content"); Toggle[] toggleList = toggleRoot.GetComponentsInChildren<Toggle>(false); for (int i = 0; i < toggleList.Length; i++) { Toggle temp = toggleList[i]; temp.onValueChanged.RemoveAllListeners(); temp.isOn = false; temp.onValueChanged.AddListener(x => OnSelectItemEx(temp)); } } public override void OnPointerClick(PointerEventData eventData) { ShowController(); } public void OnSelectItemEx(Toggle toggle) { if (!toggle.isOn) { toggle.isOn = true; return; } int selectedIndex = -1; Transform tr = toggle.transform; Transform parent = tr.parent; for (int i = 0; i < parent.childCount; i++) { if (parent.GetChild(i) == tr) { // Subtract one to account for template child. selectedIndex = i - 1; break; } } if (selectedIndex < 0) return; if (value == selectedIndex && m_AlwaysCallback) onValueChanged.Invoke(value); else value = selectedIndex; Hide(); } }
4.把脚本添加到下拉框上面会出现新的组件(如下图所示)
箭头处需要自己拖上去
5.创建一个Editor脚本放在Editor文件夹下
using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEditor; using UnityEditor.UI; [CustomEditor(typeof(DropdownEx), true)] [CanEditMultipleObjects] public class DropdowmExEditor : DropdownEditor { SerializedProperty m_AlwaysCallback; protected override void OnEnable() { base.OnEnable(); m_AlwaysCallback = serializedObject.FindProperty("m_AlwaysCallback"); } public override void OnInspectorGUI() { base.OnInspectorGUI(); EditorGUILayout.PropertyField(m_AlwaysCallback); serializedObject.ApplyModifiedProperties(); } }
需要重复点击就勾选上 m_AlwaysCallback 变量
在加一个脚本方便使用

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; public class DIO : MonoBehaviour { //private List<string> List_int = new List<string> {"DI1","DI2","DI3","DI4","DI5","DI6","DI7","DI8" }; public int DIOINT=0; [HideInInspector] public Dropdown dropdown; // Start is called before the first frame update void Start() { DIOINT = 1; dropdown = this.GetComponent<Dropdown>(); UpdateDropdownView(DIO_Setting.instance_.List_DI); dropdown.onValueChanged.AddListener(Changed); } private void Changed(int index) { switch (index ) { case 0: DIOINT = 1; ShuaXin(DIO_Setting.instance_.List_DI[0]); DIO_Setting.instance_.List_DI.RemoveAt(0); //dropdown.interactable = false; break; case 1: DIOINT = 2; ShuaXin(DIO_Setting.instance_.List_DI[1]); DIO_Setting.instance_.List_DI.RemoveAt(1); //dropdown.interactable = false; break; case 2: DIOINT = 3; ShuaXin(DIO_Setting.instance_.List_DI[2]); DIO_Setting.instance_.List_DI.RemoveAt(2); //dropdown.interactable = false; break; case 3: DIOINT = 4; ShuaXin(DIO_Setting.instance_.List_DI[3]); DIO_Setting.instance_.List_DI.RemoveAt(3); //dropdown.interactable = false; break; case 4: DIOINT = 5; ShuaXin(DIO_Setting.instance_.List_DI[4]); DIO_Setting.instance_.List_DI.RemoveAt(4); //dropdown.interactable = false; break; case 5: DIOINT = 6; ShuaXin(DIO_Setting.instance_.List_DI[5]); DIO_Setting.instance_.List_DI.RemoveAt(5); //dropdown.interactable = false; break; case 6: DIOINT = 7; ShuaXin(DIO_Setting.instance_.List_DI[6]); DIO_Setting.instance_.List_DI.RemoveAt(6); //dropdown.interactable = false; break; case 7: DIOINT = 8; ShuaXin(DIO_Setting.instance_.List_DI[7]); DIO_Setting.instance_.List_DI.RemoveAt(7); //dropdown.interactable = false; break; default: break; } } //默认显示第一条数据 public void UpdateDropdownView(List<string> showNames) { //清空下下拉框数据 this.dropdown.options.Clear(); Dropdown.OptionData tempData; for (int i = 0; i < showNames.Count; i++) { tempData = new Dropdown.OptionData(); tempData.text = showNames[i].ToString (); dropdown.options.Add(tempData); } //把第一条数据显示为默认 dropdown.captionText.text = showNames[0].ToString(); } //更新下拉框数据 public void UpdateDropdownView_1(List<string> showNames) { //清空下下拉框数据 this.dropdown.options.Clear(); Dropdown.OptionData tempData; for (int i = 0; i < showNames.Count; i++) { tempData = new Dropdown.OptionData(); tempData.text = showNames[i].ToString(); dropdown.options.Add(tempData); } } //下拉框显示选中数据 //设置默认数据 public void ShuaXin(string sows) { this.dropdown.options.Clear(); Dropdown.OptionData tempData; tempData = new Dropdown.OptionData(); tempData.text = sows.ToString(); dropdown.captionText.text = sows.ToString(); //dropdown.interactable = false; } private void Update() { //DIO_Setting.instance_.List_DI 和上面的List_int是一样的 因为要选中一个删除一个,列表要放在 //其他脚本 所以一直更新列表 UpdateDropdownView_1(DIO_Setting.instance_.List_DI); } }
最后一个实用的技巧
如果你不想下拉框一开始就是选中状态其实也是可以的
如箭头所示改成-1就行了,就是默认不选中
❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤
❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤
❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤❤
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 25岁的心里话
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器