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

简介: 当我们在使用unity自带的Toggle组件的时候,我们是通过Toggle组件上的isOn属性得知是开启我们的功能面板还是关闭,这时候通常我们会给toggle绑定一个方法,当我们点击toggle的时候,调用方法,同时播放点击音效,可是有些时候,需要我们...

当我们在使用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);
    }
 

}

相关文章
|
4月前
|
语音技术 开发工具 图形学
Unity与IOS⭐一、百度语音IOS版Demo调试方法
Unity与IOS⭐一、百度语音IOS版Demo调试方法
|
4月前
|
图形学 机器学习/深度学习 人工智能
颠覆传统游戏开发,解锁未来娱乐新纪元:深度解析如何运用Unity引擎结合机器学习技术,打造具备自我进化能力的智能游戏角色,彻底改变你的游戏体验——从基础设置到高级应用全面指南
【8月更文挑战第31天】本文探讨了如何在Unity中利用机器学习增强游戏智能。作为领先的游戏开发引擎,Unity通过ML-Agents Toolkit等工具支持AI代理的强化学习训练,使游戏角色能自主学习完成任务。文章提供了一个迷宫游戏示例及其C#脚本,展示了环境观察、动作响应及奖励机制的设计,并介绍了如何设置训练流程。此外,还提到了Unity与其他机器学习框架(如TensorFlow和PyTorch)的集成,以实现更复杂的游戏玩法。通过这些技术,游戏的智能化程度得以显著提升,为玩家带来更丰富的体验。
66 1
|
4月前
|
Java 网络安全 开发工具
UNITY与安卓⭐一、Android Studio初始设置
UNITY与安卓⭐一、Android Studio初始设置
|
4月前
|
前端开发 图形学
Unity精华☀️UI和物体可见性的判断方法
Unity精华☀️UI和物体可见性的判断方法
|
4月前
|
图形学
小功能⭐️获取Unity游戏物体上,所挂载组件的名称
小功能⭐️获取Unity游戏物体上,所挂载组件的名称
|
4月前
|
API 开发工具 vr&ar
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
PicoVR Unity SDK⭐️一、SDK下载、项目设置与程序初始配置
|
3月前
|
图形学 iOS开发 Android开发
从Unity开发到移动平台制胜攻略:全面解析iOS与Android应用发布流程,助你轻松掌握跨平台发布技巧,打造爆款手游不是梦——性能优化、广告集成与内购设置全包含
【8月更文挑战第31天】本书详细介绍了如何在Unity中设置项目以适应移动设备,涵盖性能优化、集成广告及内购功能等关键步骤。通过具体示例和代码片段,指导读者完成iOS和Android应用的打包与发布,确保应用顺利上线并获得成功。无论是性能调整还是平台特定的操作,本书均提供了全面的解决方案。
157 0
|
4月前
|
开发者 图形学 C#
深度解密:Unity游戏开发中的动画艺术——Mecanim状态机如何让游戏角色栩栩如生:从基础设置到高级状态切换的全面指南,助你打造流畅自然的游戏动画体验
【8月更文挑战第31天】Unity动画系统是游戏开发的关键部分,尤其适用于复杂角色动画。本文通过具体案例讲解Mecanim动画状态机的使用方法及原理。我们创建一个游戏角色并设计行走、奔跑和攻击动画,详细介绍动画状态机设置及脚本控制。首先导入动画资源并添加Animator组件,然后创建Animator Controller并设置状态间的转换条件。通过编写C#脚本(如PlayerMovement)控制动画状态切换,实现基于玩家输入的动画过渡。此方法不仅适用于游戏角色,还可用于任何需动态动画响应的对象,增强游戏的真实感与互动性。
110 0
|
4月前
|
开发者 图形学 iOS开发
掌握Unity的跨平台部署与发布秘籍,让你的游戏作品在多个平台上大放异彩——从基础设置到高级优化,深入解析一站式游戏开发解决方案的每一个细节,带你领略高效发布流程的魅力所在
【8月更文挑战第31天】跨平台游戏开发是当今游戏产业的热点,尤其在移动设备普及的背景下更为重要。作为领先的游戏开发引擎,Unity以其卓越的跨平台支持能力脱颖而出,能够将游戏轻松部署至iOS、Android、PC、Mac、Web及游戏主机等多个平台。本文通过杂文形式探讨Unity在各平台的部署与发布策略,并提供具体实例,涵盖项目设置、性能优化、打包流程及发布前准备等关键环节,助力开发者充分利用Unity的强大功能,实现多平台游戏开发。
113 0
|
4月前
|
图形学 C# 开发者
Unity粒子系统全解析:从基础设置到高级编程技巧,教你轻松玩转绚丽多彩的视觉特效,打造震撼游戏画面的终极指南
【8月更文挑战第31天】粒子系统是Unity引擎的强大功能,可创建动态视觉效果,如火焰、爆炸等。本文介绍如何在Unity中使用粒子系统,并提供示例代码。首先创建粒子系统,然后调整Emission、Shape、Color over Lifetime等模块参数,实现所需效果。此外,还可通过C#脚本实现更复杂的粒子效果,增强游戏视觉冲击力和沉浸感。
250 0