美文网首页unity3D技术分享unityUnity技术分享
unity3d自定义Toggle组件,解决设置isOn自动调用方

unity3d自定义Toggle组件,解决设置isOn自动调用方

作者: 好怕怕 | 来源:发表于2016-12-27 21:33 被阅读8084次

    当我们在使用unity自带的Toggle组件的时候,我们是通过Toggle组件上的isOn属性得知是开启我们的功能面板还是关闭,这时候通常我们会给toggle绑定一个方法,当我们点击toggle的时候,调用方法,同时播放点击音效,可是有些时候,需要我们在切换界面的时候通过其它方法来关闭我们的属性isOn为false,方便我们下次点击的时候,isOn为true,这时候,我们单独对toggle的isOn属性赋值时会调用一次我们的方法,同时还会播放一次声音,恶心的事情就此发生,所以在项目中不得不重写了此组件,以方便项目中多处使用,下面是MyToggle脚本,挂载到对象身上即可,和unity自带的Toggle用法一样,只是在手动设置isOn属性的时候不会自动调用方法。

    using System;
    using UnityEditor;
    using UnityEngine;
    using UnityEngine.Events;
    using UnityEngine.EventSystems;
    using UnityEngine.Serialization;
    using UnityEngine.UI;
    
    /// <summary>
    /// 自定义Toggle组件
    /// </summary>
    [RequireComponent(typeof(RectTransform))]
    public class MyToggle : Selectable, IEventSystemHandler, IPointerClickHandler, ISubmitHandler, ICanvasElement
    {
    
        /// <summary>
        /// toggle为true时切换显示的底图
        /// </summary>
        public Graphic m_ChangeImage;
    
        [SerializeField]
        [FormerlySerializedAs("m_IsActive")]
        private bool m_IsOn;
    
        public MyToggle.ToggleTransition toggleTransition = MyToggle.ToggleTransition.Fade;
    
        public Toggle.ToggleEvent onValueChanged = new Toggle.ToggleEvent();
        
        /// <summary>
        /// 设置ison属性(自动调用一次方法)
        /// </summary>
        public bool isOn
        {
            get
            {
                return this.m_IsOn;
            }
            set
            {
                this.Set(value);
            }
        }
    
        /// <summary>
        /// 设置ison属性(不会自动调用方法)
        /// </summary>
        public bool IsOn
        {
            get
            {
                return this.m_IsOn;
            }
            set
            {
                this.Set(value, value, value);
            }
        }
    
    
        protected MyToggle()
        {
        }
    
        public virtual void Rebuild(CanvasUpdate executing)
        {
            if (executing != CanvasUpdate.Prelayout)
                return;
            this.onValueChanged.Invoke(this.m_IsOn);
        }
    
    
        public virtual void LayoutComplete()
        {
        }
    
    
        public virtual void GraphicUpdateComplete()
        {
        }
    
        protected override void OnEnable()
        {
            base.OnEnable();
            this.PlayEffect(true);
            this.IsOn = false;
        }
    
    
        protected override void OnDisable()
        {
            base.OnDisable();
            this.IsOn = false;
        }
    
    
        private void Set(bool value)
        {
            this.Set(value, true);
        }
    
        private void Set(bool value, bool sendCallback)
        {
            if (this.m_IsOn == value)
                return;
            this.m_IsOn = value;
            this.PlayEffect(this.toggleTransition == MyToggle.ToggleTransition.None);
    
            if (!sendCallback)
                return;
            this.onValueChanged.Invoke(this.m_IsOn);
        }
    
        private void Set(bool value, bool sendCallback, bool call)
        {
            if (this.m_IsOn == value)
                return;
            this.m_IsOn = value;
            this.PlayEffect(this.toggleTransition == MyToggle.ToggleTransition.None);
    
            if (!sendCallback)
                return;
        }
    
        private void InternalToggle()
        {
            if (!this.IsActive() || !this.IsInteractable())
                return;
            this.isOn = !this.isOn;
        }
    
        /// <summary>
        /// 点击事件
        /// </summary>
        /// <param name="eventData">Current event.</param>
        public virtual void OnPointerClick(PointerEventData eventData)
        {
            if (eventData.button != PointerEventData.InputButton.Left)
                return;
            this.InternalToggle();
        }
    
        public virtual void OnSubmit(BaseEventData eventData)
        {
            this.InternalToggle();
        }
         
    
        public enum ToggleTransition
        {
            None,
            Fade,
        }
    
    
        [Serializable]
        public class ToggleEvent : UnityEvent<bool>
        {
        }
    
        protected override void OnDidApplyAnimationProperties()
        {
            if ((UnityEngine.Object)this.m_ChangeImage != (UnityEngine.Object)null)
            {
                bool flag = !Mathf.Approximately(this.m_ChangeImage.canvasRenderer.GetColor().a, 0.0f);
                if (this.m_IsOn != flag)
                {
                    this.m_IsOn = flag;
                    this.Set(!flag);
                }
            }
            base.OnDidApplyAnimationProperties();
        }
    
        private void PlayEffect(bool instant)
        {
            if ((UnityEngine.Object)this.m_ChangeImage == (UnityEngine.Object)null)
                return;
            if (!Application.isPlaying)
                this.m_ChangeImage.canvasRenderer.SetAlpha(!this.m_IsOn ? 0.0f : 1f);
            else
                this.m_ChangeImage.CrossFadeAlpha(!this.m_IsOn ? 0.0f : 1f, !instant ? 0.1f : 0.0f, true);
        }
        protected override void Start()
        {
            this.PlayEffect(true);
        }
        protected override void OnValidate()
        {
            base.OnValidate();
            this.Set(this.m_IsOn, false);
            this.PlayEffect(this.toggleTransition == MyToggle.ToggleTransition.None);
            if (PrefabUtility.GetPrefabType((UnityEngine.Object)this) == PrefabType.Prefab || Application.isPlaying)
                return;
            CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild((ICanvasElement)this);
        }
     
    
    }
    
    

    相关文章

      网友评论

        本文标题:unity3d自定义Toggle组件,解决设置isOn自动调用方

        本文链接:https://www.haomeiwen.com/subject/plvevttx.html