本文共 4545 字,大约阅读时间需要 15 分钟。
当我们在使用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;////// 自定义Toggle组件/// [RequireComponent(typeof(RectTransform))]public class MyToggle : Selectable, IEventSystemHandler, IPointerClickHandler, ISubmitHandler, ICanvasElement{ ////// toggle为true时切换显示的底图 /// 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(); ////// 设置ison属性(自动调用一次方法) /// public bool isOn { get { return this.m_IsOn; } set { this.Set(value); } } ////// 设置ison属性(不会自动调用方法) /// 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; } ////// 点击事件 /// /// Current event. 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{ } 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); } }
转载地址:http://hxyqa.baihongyu.com/