ugui的Toggle组件小改造
主要改动以下几个地方:
1) 考虑下面的几个使用场景:
a) 有多个功能页签,某个页签要玩家等级10级才可以切换过去,不满10级的时候,点击该页签提示:10级后开启
不可ToggleOn
b) 合成道具的时候,最多勾选4个道具,选择第5个时,不能勾选上,且提示:最多选择4个道具
不可ToggleOn
c) 副本开启期间,可以多次邀请好友加入副本,打开好友邀请界面时,已邀请过的好友也会显示在里面,只是默认已勾选,且不能勾掉。尝试勾掉会提示:该玩家已邀请
不可ToggleOff
所以,在Toggle触发前,增加一个确认逻辑,是否能触发Toggle
2) Set函数private改为public,只想设置isOn而不想触发回调还是有用的
改动部分都标黄了
using System; using UnityEngine.Events; using UnityEngine.EventSystems; using UnityEngine.Serialization; namespace UnityEngine.UI { /// <summary> /// A standard toggle that has an on / off state. /// </summary> /// <remarks> /// The toggle component is a Selectable that controls a child graphic which displays the on / off state. /// When a toggle event occurs a callback is sent to any registered listeners of UI.Toggle._onValueChanged. /// </remarks> [AddComponentMenu("UI/Toggle", 31)] [RequireComponent(typeof(RectTransform))] public class Toggle : Selectable, IPointerClickHandler, ISubmitHandler, ICanvasElement { /// <summary> /// Display settings for when a toggle is activated or deactivated. /// </summary> public enum ToggleTransition { /// <summary> /// Show / hide the toggle instantly /// </summary> None, /// <summary> /// Fade the toggle in / out smoothly. /// </summary> Fade } [Serializable] /// <summary> /// UnityEvent callback for when a toggle is toggled. /// </summary> public class ToggleEvent : UnityEvent<bool> {} /// <summary> /// Transition mode for the toggle. /// </summary> public ToggleTransition toggleTransition = ToggleTransition.Fade; /// <summary> /// Graphic the toggle should be working with. /// </summary> public Graphic graphic; [SerializeField] private ToggleGroup m_Group; /// <summary> /// Group the toggle belongs to. /// </summary> 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> /// <example> /// <code> /// //Attach this script to a Toggle GameObject. To do this, go to Create>UI>Toggle. /// //Set your own Text in the Inspector window /// /// using UnityEngine; /// using UnityEngine.UI; /// /// public class Example : MonoBehaviour /// { /// Toggle m_Toggle; /// public Text m_Text; /// /// void Start() /// { /// //Fetch the Toggle GameObject /// m_Toggle = GetComponent<Toggle>(); /// //Add listener for when the state of the Toggle changes, to take action /// m_Toggle.onValueChanged.AddListener(delegate { /// ToggleValueChanged(m_Toggle); /// }); /// /// //Initialise the Text to say the first state of the Toggle /// m_Text.text = "First Value : " + m_Toggle.isOn; /// } /// /// //Output the new state of the Toggle into Text /// void ToggleValueChanged(Toggle change) /// { /// m_Text.text = "New Value : " + m_Toggle.isOn; /// } /// } /// </code> /// </example> public ToggleEvent onValueChanged = new ToggleEvent(); // Whether the toggle is on [Tooltip("Is the toggle currently on or off?")] [SerializeField] private bool m_IsOn; /// <summary> /// 触发Toggle前, 确认是否可触发 /// </summary> public delegate bool ToggleConfirmFunc(Toggle t); private ToggleConfirmFunc m_ToggleConfirm; public ToggleConfirmFunc toggleConfirm { get { return m_ToggleConfirm; } set { m_ToggleConfirm = value; } } protected Toggle() {} #if UNITY_EDITOR protected override void OnValidate() { base.OnValidate(); if (!UnityEditor.PrefabUtility.IsPartOfPrefabAsset(this) && !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> /// <example> /// <code> /// /Attach this script to a Toggle GameObject. To do this, go to Create>UI>Toggle. /// //Set your own Text in the Inspector window /// /// using UnityEngine; /// using UnityEngine.UI; /// /// public class Example : MonoBehaviour /// { /// Toggle m_Toggle; /// public Text m_Text; /// /// void Start() /// { /// //Fetch the Toggle GameObject /// m_Toggle = GetComponent<Toggle>(); /// //Add listener for when the state of the Toggle changes, and output the state /// m_Toggle.onValueChanged.AddListener(delegate { /// ToggleValueChanged(m_Toggle); /// }); /// /// //Initialize the Text to say whether the Toggle is in a positive or negative state /// m_Text.text = "Toggle is : " + m_Toggle.isOn; /// } /// /// //Output the new state of the Toggle into Text when the user uses the Toggle /// void ToggleValueChanged(Toggle change) /// { /// m_Text.text = "Toggle is : " + m_Toggle.isOn; /// } /// } /// </code> /// </example> public bool isOn { get { return m_IsOn; } set { Set(value); } } void Set(bool value) { Set(value, true); } public 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()) { if (m_IsOn || (!m_Group.AnyTogglesOn() && !m_Group.allowSwitchOff)) { 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) { UISystemProfilerApi.AddMarker("Toggle.value", this); onValueChanged.Invoke(m_IsOn); } } /// <summary> /// Play the appropriate effect. /// </summary> private void PlayEffect(bool instant) { 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; if (null != m_ToggleConfirm) { if (m_ToggleConfirm(this)) InternalToggle(); } else { InternalToggle(); } } public virtual void OnSubmit(BaseEventData eventData) { InternalToggle(); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2022-06-28 NavMesh-动态生成寻路数据