-
Unity UGUI入门组件整理(三)【Toggle组件与Toggle Group组件】
2021-01-06 17:29:18Toggle:选项组件(单选框,多选框),功能和button差不多,有时候我们会用Toggle组件代替Button组件; Toggle组件与Toggle Group组件:经常成对出现; toggle Group与Toggle属于父子关系,Toggle常作为Toggle Group...Toggle:选项组件(单选框,多选框),功能和button差不多,有时候我们会用Toggle组件代替Button组件;
Toggle组件与Toggle Group组件:经常成对出现;
toggle Group与Toggle属于父子关系,Toggle常作为Toggle Group组件的子物体,从来来实现单选和多选的效果 。1、Toggle组件:首先我们在Panel下新建空物体GameObject,改名为Toggle Group;
选中Toggle Group,右击在UI里添加Toggle组件,如图:
2、展开Toggle组件,我们发现,他包含有两个image组件和一个Label(文本输入框)【Text】组件;
Background:背景图片,控制toggle组件的背景颜色改变,从而展示此物体是否被选中的效果;
Checkmark:就是我们界面看到的对号勾选框,对号图片可以替换,也可以删除不用。
Label:text组件:文本输出框,我们可以在这里输入文字,说明这个Toggle的作用或名称;
3、下面我们来看Toggle的菜单:
前面讲过的不再重复;
大多数菜单功能与Button类同;
Is On:用来表示Toggle当前开关状态,勾选为开;
Graphic:控制Toggle组件开关图片的显示隐藏,默认选取Checkmark;
Group:这里放Toggle属于的开关组,在下面的Toggle Group中详细讲。
4、Toggle:的添加事件:using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class ToggleConllter : MonoBehaviour { private Toggle toggle;//注册toggle组件 // Start is called before the first frame update void Start() { //获取Toggle组件 toggle = gameObject.GetComponent<Toggle>(); //绑定按钮点击事件 toggle.onValueChanged.AddListener(ison => print(ison?"开":"关")) ; } // Update is called once per frame void Update() { } }
5、Toggle Group
(1)在空物体上,如上图,添加Toggle Group组件;
(2)
下面我们来简单介绍一下Toggle Group组件;
非常的简单,可以看到只有一个选项框:
Allow Switch off:Allow Switch off处于选中状态,表示该物体的子物体都带有Toggle组件,且每次只有一个Toggle可以处于被选中状态(也就是单选状态);
如果没有勾选Allow Switch off:则该物体下带有Toggle的子物体,可以一次选中多个(也就是多选状态)
(3)那么具体要怎么做呢?
这时我们要结合上面Toggle的预留问题:Group
当我们的父物体上有Toggle Group组件且该物体的子物体上有Toggle组件时;
我们就可以建立一个按钮组,用来控制所有Toggle组件的选择;
具体操作:
选中所有含有Toggle组件的子物体,在子物体的Toggle菜单栏上找到Group栏,把父物体拖拽添加到个Group:如图所示:
这样便实现了按钮组的操作。我简单写了一个Toggle Group类的控制方法:大家可以参考一下。
using System.Collections; using System.Collections.Generic; using System.Linq; using UnityEngine; using UnityEngine.UI; public class ToggleGroupControl : MonoBehaviour { /// <summary> /// 建立Toggle列表,存取所有的Toggle,便于调用操作 /// </summary> [SerializeField] List<Toggle> ToggleList = new List<Toggle>(); // Start is called before the first frame update void Start() { //给list赋值 ToggleList = transform.GetComponentsInChildren<Toggle>().ToList(); //遍历Toggle Group下的所有Toggle for (int i = 0; i < ToggleList.Count; i++) { var toggle = ToggleList[i]; var a = i; //绑定Toggle事件 toggle.onValueChanged.AddListener(delegate (bool ison) { this.OnValueChanged(ison, a); }); } } // Update is called once per frame void Update() { } public void OnValueChanged(bool ison, int value) { if (ison) { print("执行你的选中方法"); } } }
-
UGUI源码之Toggle组件
2020-12-08 23:50:19最近在像往常一样使用Toggle组件的时候,遇到一个问题:之前一直认为toggle组件是控制对象显示和隐藏从而实现单选的效果。然后那天一不小心将toggle组件控制的对象给手动隐藏掉了,然后发现改变toggle的IsOn属性无法...最近在像往常一样使用Toggle组件的时候,遇到一个问题:之前一直认为toggle组件是控制对象显示和隐藏从而实现单选的效果。然后那天一不小心将toggle组件控制的对象给手动隐藏掉了,然后发现改变toggle的IsOn属性无法达到单选的效果。接着就引发了思考,原来之前的理解是错误的。于是看了一下UGUI的源码是怎么实现的。
先来看下自己测试的结构:
然后说下其中的几个方法:
这个方法里面m_Group代表的就是我们测试的结构第二张图里面Toggle组件下绑定的Group,它是一个挂载了ToggleGroup组件的对象,大家应该知道Toggle组件的使用方法,就不多说了。这个方法里面主要是将当前的Toggle添加到ToggleGroup中来。代码的第二张图是ToggleGroup类中的方法。
这一段代码表示的就是:Toggle组件如何控制对象的淡入淡出。所以Toggle组件并不是将对象进行了显示隐藏。当m_isOn == true,CrossFadeAlpha()传入的第一个参数是1,这个1是做什么用的呢,继续往下看看
原来这个1这个位置的参数是决定透明度的。到这里我的疑惑就解决了,当然我没有继续深入研究这个方法,只是稍微了解了一下这个流程,以后再仔细研究。
再回到PlayEffect方法中来,上面提到了CrossFadeAlpha()方法,然后接下来说一下SetAlpha(),这个看上去也是像设置透明度,具体怎么操作的源码没有提供进一步的实现。不过知道的是这个代码是在Editor模式下就运行了 这也就是为什么我们项目结构的图片中我的Image没有显示出来的原因。
上面这一部分代码就是我们点击了IsOn以后的操作了,最终会执行到我们的PlayerEffect方法从而实现淡入淡出效果。这里有个M_Group.NotifyToggleOn(this)来说下这个方法的作用。
先来说下上面那个判断:m_Group.AnyTogglesOn()这个代表是否有开关打开了。m_Group.allowSwitchOff这个就是指我们的ToggleGroup组件下的勾选项
m_Group.allowSwitchOff默认为false,那么必须有且只有一个toggle的isOn为true。勾选中以后m_Group.allowSwitchOff = true,表示允许所有的Toggle组件isOn为false
来看看NotifyToggleOn做了什么操作吧:
其实就是把之前通过SetToggleGroup()方法添加进来的Toggle组件的ison设置为了false。
整理下完整的点击了IsOn的流程:
OnPointClick()就是被点击中触发的方法,关于点击的流程感兴趣的可以看看这个博客https://blog.csdn.net/wangjianxin97/article/details/96604461,然后贴上来整个Toggle的源码吧
using System; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.Serialization; namespace UnityEngine.UI { /// <summary> /// Simple toggle -- something that has an 'on' and 'off' states: checkbox, toggle button, radio button, etc. /// </summary> [AddComponentMenu("UI/Toggle", 31)] [RequireComponent(typeof(RectTransform))] public class Toggle : Selectable, IPointerClickHandler, ISubmitHandler, ICanvasElement { public enum ToggleTransition { None, Fade } [Serializable] public class ToggleEvent : UnityEvent<bool> {} /// <summary> /// Transition type. /// </summary> public ToggleTransition toggleTransition = ToggleTransition.Fade; /// <summary> /// Graphic the toggle should be working with. /// </summary> public Graphic graphic; // group that this toggle can belong to [SerializeField] private ToggleGroup m_Group; public ToggleGroup group { get { return m_Group; } set { m_Group = value; #if UNITY_EDITOR if (Application.isPlaying) #endif { SetToggleGroup(m_Group, true); PlayEffect(true); } } } /// <summary> /// Allow for delegate-based subscriptions for faster events than 'eventReceiver', and allowing for multiple receivers. /// </summary> public ToggleEvent onValueChanged = new ToggleEvent(); // Whether the toggle is on [FormerlySerializedAs("m_IsActive")] [Tooltip("Is the toggle currently on or off?")] [SerializeField] private bool m_IsOn; protected Toggle() {} #if UNITY_EDITOR protected override void OnValidate() { base.OnValidate(); var prefabType = UnityEditor.PrefabUtility.GetPrefabType(this); if (prefabType != UnityEditor.PrefabType.Prefab && !Application.isPlaying) CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild(this); } #endif // if UNITY_EDITOR public virtual void Rebuild(CanvasUpdate executing) { #if UNITY_EDITOR if (executing == CanvasUpdate.Prelayout) onValueChanged.Invoke(m_IsOn); #endif } public virtual void LayoutComplete() {} public virtual void GraphicUpdateComplete() {} protected override void OnEnable() { base.OnEnable(); SetToggleGroup(m_Group, false); PlayEffect(true); } protected override void OnDisable() { SetToggleGroup(null, false); base.OnDisable(); } protected override void OnDidApplyAnimationProperties() { // Check if isOn has been changed by the animation. // Unfortunately there is no way to check if we don�t have a graphic. if (graphic != null) { bool oldValue = !Mathf.Approximately(graphic.canvasRenderer.GetColor().a, 0); if (m_IsOn != oldValue) { m_IsOn = oldValue; Set(!oldValue); } } base.OnDidApplyAnimationProperties(); } private void SetToggleGroup(ToggleGroup newGroup, bool setMemberValue) { ToggleGroup oldGroup = m_Group; // Sometimes IsActive returns false in OnDisable so don't check for it. // Rather remove the toggle too often than too little. if (m_Group != null) m_Group.UnregisterToggle(this); // At runtime the group variable should be set but not when calling this method from OnEnable or OnDisable. // That's why we use the setMemberValue parameter. if (setMemberValue) m_Group = newGroup; // Only register to the new group if this Toggle is active. if (newGroup != null && IsActive()) newGroup.RegisterToggle(this); // If we are in a new group, and this toggle is on, notify group. // Note: Don't refer to m_Group here as it's not guaranteed to have been set. if (newGroup != null && newGroup != oldGroup && isOn && IsActive()) newGroup.NotifyToggleOn(this); } /// <summary> /// Whether the toggle is currently active. /// </summary> public bool isOn { get { return m_IsOn; } set { Set(value); } } void Set(bool value) { Set(value, true); } void Set(bool value, bool sendCallback) { if (m_IsOn == value) return; // if we are in a group and set to true, do group logic m_IsOn = value; if (m_Group != null && IsActive()) { Debug.Log("m_Group.AnyTogglesOn()"+m_Group.AnyTogglesOn()); if (m_IsOn || (!m_Group.AnyTogglesOn() && !m_Group.allowSwitchOff)) { Debug.Log("m_IsOn = " + m_IsOn); m_IsOn = true; m_Group.NotifyToggleOn(this); } } // Always send event when toggle is clicked, even if value didn't change // due to already active toggle in a toggle group being clicked. // Controls like Dropdown rely on this. // It's up to the user to ignore a selection being set to the same value it already was, if desired. PlayEffect(toggleTransition == ToggleTransition.None); if (sendCallback) onValueChanged.Invoke(m_IsOn); } /// <summary> /// Play the appropriate effect. /// </summary> private void PlayEffect(bool instant) { Debug.Log("m_IsOn" + m_IsOn); if (graphic == null) return; #if UNITY_EDITOR if (!Application.isPlaying) { graphic.canvasRenderer.SetAlpha(m_IsOn ? 1f : 0f); } else #endif { graphic.CrossFadeAlpha(m_IsOn ? 1f : 0f, instant ? 0f : 0.1f, true); } } /// <summary> /// Assume the correct visual state. /// </summary> protected override void Start() { PlayEffect(true); } private void InternalToggle() { if (!IsActive() || !IsInteractable()) return; isOn = !isOn; } /// <summary> /// React to clicks. /// </summary> public virtual void OnPointerClick(PointerEventData eventData) { if (eventData.button != PointerEventData.InputButton.Left) return; InternalToggle(); } public virtual void OnSubmit(BaseEventData eventData) { InternalToggle(); } } }
-
Cocos Creator (Toggle组件详解)
2019-04-04 16:10:45前言 Toggle 是一个 CheckBox,他可以与 ToggleGroup/ToggleContainer 一起使用,也就是多项单选按钮。...想要查看 Toggle组件 的API,请点击这里,这里截取部分 Toggle组件 的API用作说明。 · · ...前言
Toggle
是一个CheckBox
,他可以与ToggleGroup/ToggleContainer
一起使用,也就是多项单选按钮。Toggle 组件
点击 属性检查器 下面的
添加组件
按钮,然后选择 UI组件 中的Toggle
,即可将 Toggle 组件 添加至节点。想要查看 Toggle组件 的API,请点击这里,这里截取部分 Toggle组件 的API用作说明。
·
·
·Toggle 的属性
属性(properties) 说明 target Node
需要过渡的目标。(所选目标,一般为本身添加 Toggle
组件,所以目标为本身Node
节点)interactable Boolean
按钮事件是否被响应,如果为 false
,则按钮将被禁用,无法点击。enableAutoGrayEffect Boolean
如果设置为 true
,当Toggle
的interactable
属性为false
的时候,会使用内置shader
让Toggle
的target
节点的sprite
组件变灰。transition Button.Transition
按钮状态改变时过渡方式。 NONE:
点击时无过渡效果,COLOR:
点击时进行颜色变化,SPRITE:
点击时更改精灵图,SCALE:
点击时改变按钮的大小。isChecked Boolean
如果设置为 true
,则 check mark 组件会处于enabled
状态,否则处于disabled
状态。checkMark Sprite
Toggle
处于选中状态时显示的图片。toggleGroup ToggleGroup
Toggle
所属的ToggleGroup
,这个属性是可选的。配合旧版单选组件ToggleGroup
使用checkEvents Component.EventHandler[]
Toggle 按钮的点击事件列表。 Toggle 的点击事件
属性 功能说明 target 带有脚本组件所在的节点 component 绑定脚本组件的名称 handler 指定一个方法为绑定的回调方法,填写方法名即可 customEventData 用户指定任意的字符串作为事件回调的最后一个参数传入 如果想要进行代码绑定,可以自定义事件进行绑定,也可直接在属性面板上进行拖拽绑定。
TestMgr.js let check = new cc.Component.EventHandler(); // 创建一个新的事件回调 check.target = this.node; // 绑定回调方法所在的节点 check.component = "TestMgr"; // 绑定回调方法所在的脚本名字 check.handler = "OnValueChanged"; // 绑定的回调方法的名字 check.customEventData = "changed"; // 绑定的回调方法的参数
OnValueChanged : function ( toggle, customEventData ){}
Toggle事件的回调参数有两个: 第一个是
Toggle
本身,第二个参数是customEventData
。
·Toggle 的回调绑定 (由简入繁)
·方法一(属性检查器中直接拖拽想要绑定的方法)
拖拽绑定,将带有Toggle方法的脚本节点拖入对应Toggle的CheckEvents中,可以自定义回调参数。 (缺点,灵活性与可拓展性太差,团队越大代码量越多,维护起来越难。如果功能唯一也可以,不太推荐)
cc.Class({ extends: cc.Component, properties: {}, ToggleMgr.js ==> // 要注意,回调自定义参数的类型为 String ToggleEvent: function ( toggleSelf, customEventData ) { // 回调参数1就是toggle本身,参数2为自定义数据("check this toggle") } });
·方法二(Node监听)
将要绑定方法的Toogle节点拖拽至ToggleMgr属性检查器中的Toggle属性上。 通过node监听方式绑定toggle方法。 四个监听参数(监听类型,监听回调方法,执行监听回调方法的目标,触发阶段(一般来说不需要设置)) (缺点,作者自认为)此方法不支持传递回调自定义参数。
cc.Class({ extends: cc.Component, properties: { toggle: cc.Toggle }, onLoad: function () { this.toggle.node.on('toggle', this.ToggleEvent, this); }, ToggleMgr.js==> ToggleEvent: function (event) { var toggle = event; if(toggle.isChecked) console.log("toggle is checked"); else console.log("toggle is unchecked"); } });
·方法三(代码添加回调)
·将 ToggleItem.js 添加至目标Toggle节点上。 脚本在加载时将会自动绑定监听。 (优点,只要将脚本添加至目标节点上,就直接绑定了事件监听。) (缺点,当toggle数量过多时,在场景中占用的内存也会增大)
ToggleItem.js ==> cc.Class({ extends: cc.Component, properties: {}, onLoad () { let check = new cc.Component.EventHandler();// 创建一个新的事件处理 check.target = this.node; // 绑定回调方法所在的节点 check.component = "ToggleItem"; // 绑定回调方法所在的脚本名字 check.handler = "OnValueChanged"; // 绑定的回调方法的名字 check.customEventData = "Changed"; // 绑定的回调方法的参数 let toggle = this.node.getComponent(cc.Toggle); if (toggle){ toggle.checkEvents = []; // 清空toggle的回调事件列表 toggle.checkEvents.push(check); // 将方法绑定到指定toggle } }, OnValueChanged: function(toggle, customEventData) { if(toggle.isChecked) console.log(customEventData); }, });
·方法四(统一代码添加回调)
将Toggle相关方法统一放置在ToggleMgr.js 管理类中进行管理。
ToggleMgr.js ==> cc.Class({ extends: cc.Component, properties: { race: [cc.Toggle], power: [cc.Toggle], _race:[],_power:[] }, onLoad () { this._race = ["Genie","Skeleton","Terran"]; this._power = ["100-120","90-140","110-130"]; this.AddListener( this.race, this._race, "RaceChanged" ); this.AddListener( this.power, this._power , "PowerChanged" ); }, AddListener: function( toggles, datas, func ) { if( toggles ){ let length = toggles.length; let _length = this.datas.length; for(let i= 0; i< length; i++){ if(i<_length){ let check = new cc.Component.EventHandler();// 创建一个新的事件处理 check.target = this.node; // 绑定回调方法所在的节点 check.component = "ToggleMgr"; // 绑定回调方法所在的脚本名字 check.handler = func; // 绑定的回调方法的名字 check.customEventData = this.datas[i]; // 绑定的回调方法的参数 this.toggles[i].checkEvents = []; // 清空 toggle 回调事件列表 this.toggles[i].checkEvents.push(check); // 将方法绑定到指定 toggle } } } } RaceChanged: function(toggle, customEventData) { if(toggle.isChecked) console.log("Now, you're a ", customEventData); }, PowerChanged: function(toggle, customEventData) { if(toggle.isChecked) console.log("You choose ",customEventData); }, });
欢迎留言交流技术
-
Unity 之 UGUI Toggle组件介绍和简例
2020-02-21 22:07:27Unity 之 UGUI Toggle组件介绍和简例Unity 之 UGUI Toggle组件介绍和简例
复合组件Toggle的组成:
Toggle:自身挂载Toggle组件,并且对有对子物体的引用。
Background:就是个Image组件,用来当背景图片
Checkmark: 也是个Image组件,用来作为选中和未选中的标识
Label :是一个Text,用来描述这个Toggle组件的用处
个人理解:一个单选框,通过修改子物体的各个属性来实现开发者要实现的效果。
Toggle的属性面板:
Interactable:是否可操作,通过这个属性来控制组件是否可被点击触发
Transition:过渡,系统提供了四种方式。 1
Is On:通过这个属性控制选中和未选中的状态
Toggle Transition:切换过渡
Graphic:标识选中的UI图片
Group:通过这个属性来实现多个Toggle之间的单选2
using UnityEngine; using UnityEngine.UI; public class ToggleDemo : MonoBehaviour { Toggle toggle; void GetAttributes() { //是否可用 toggle.interactable = true; //过渡模式 toggle.transition = Selectable.Transition.ColorTint; //选中状态 toggle.isOn = true; //指定组 toggle.group = GetComponent<ToggleGroup>(); //当其值发生变化时,切换的反应方式 toggle.toggleTransition = Toggle.ToggleTransition.Fade; //ToggleTransition.None //当状态被改变时触发 toggle.onValueChanged.AddListener((bool v) => { OnChanged(v); }); } void OnChanged(bool v) { //当前Toggle组件被触发了,todo sth... } }
-
unity 用Toggle组件实现单选功能
2020-08-05 14:17:32创建Image作为挂载Toggle组件的物体,层级关系如下 Toggle组件中要拖放两个参数 Graphic参数拖入黑色图片(就是需要作为选中框的的那个图片) Group 参数拖入第一步中挂载了Toggle Group的那个物体 挂载完毕,把... -
UGUI组件之Toggle 组件简单笔记
2018-02-27 00:14:00Toggle 组件========================================================Toggle 切换键 复选框========================================================组成部分: Toggle 核心组件 --Image 背景图片 --... -
Toggle 组件参考
2020-12-09 04:18:41<div><p>URL : https://github.com/cocos-creator/creator-docs/blob/master/zh/components/toggle.md</p> 场景里面添加一组单选框 有3个 每个单选框组件 都有个isChecked 打钩 ●○○ 创建默认是这样的 直接在组件... -
UGUI—利用toggle组件实现面板的切换
2016-12-11 22:16:41Toggle组件属性 主要用到的属性: Is On:表示被选与否,其下有三个属性: Toggle Transition:切换方式 Graphic:被选中时切换出的图片 Group:所属的Toggle Group 一个事件: On Value Changed;被选状态... -
unity3d自定义Toggle组件,解决设置isOn自动调用方法
2016-12-27 21:33:00当我们在使用unity自带的Toggle组件的时候,我们是通过Toggle组件上的isOn属性得知是开启我们的功能面板还是关闭,这时候通常我们会给toggle绑定一个方法,当我们点击toggle的时候,调用方法,同时播放点击音效,... -
Unity UI时间交互 Button组件 Toggle组件 Slider组件 InputFiled组件
2019-06-19 15:46:00Toggle的回调函数拖给左右的Toggle组件 不相应关闭事件 相应开启事件,通过ToggleGroup中ActiveToggles()获取开启的Toggle 根据开启Toggle的名称执行相应代码 Slider组件 Fill ... -
unity Toggle组件添加触发事件回调
2021-01-12 23:40:24private Toggle toggle; // Use this for initialization void Start () { toggle.onValueChanged.AddListener((bool isOn)=> { OnToggleClick(toggle,isOn); }); } private void OnToggleClick(Togg -
Unity toggle组件设置选中状态和未选中状态颜色
2021-01-04 10:16:55Toggle toggle = self.GetComponent<Toggle>(); //toggle.group = toggleGroup; toggle.onValueChanged.AddListener(isOn => { ColorBlock cb = toggle.colors; if (isOn) { cb.n... -
【Cocos Creator实战教程(9)】——UI组件(3)Toggle 组件
2019-09-26 20:22:041. 相关知识点 Toggle是一个CheckBox,当它和ToggleGroup一起使用的时候,可以变成RadioButton。也就是经常用到的选择、多选按钮 ... isChecked 布尔类型,如果这个设置为 true,则 check mark 组件会处于 enable...