Skip to content

wzasd/NiceToggleUnity

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 

Repository files navigation

NiceToggleUnity

Perfect Toggle effect ##目标 本文将从 0 教你如何打造一个 Unity 的组件,来创建属于你的 UGUI~ 效果图在这里: TogglePrefer.gif ##动起来 如果是你想要的效果,那么跟我一起动起来,如果不是请点击右上角~ 本文的项目已上传 github 可以直接使用 Unity 打开使用,不想看教程,代码一样说明一切。 如要代码请点击这里

创建 Canvas

所有的 UI 空间都需要在 Canvas 下进行布局,当然这是废话。 image.png 所有的 UI 都会出现在摄像机面前了。

创建一个 Panel

对这里创建一个 Panel,来放下我们所有的组件,毕竟要手写一个 Toggle。这里起名叫做 NiceToggle。 大小设置为 200*70 。按照你的需求来。 image.png 现在我们的组件是这样的结构。 image.png 这是最基础的东西,下面就来加快速度了。

创建属于你的背景、滑块、ON文字、OFF 文字、需要相应的 Button

我们这里使用 Button 来响应用户的点击,当然你也可以用别的相应点击效果。

  • 背景是 Image 组件,起名为 ToggleBg。
  • 滑块是 Image 组件,起名为 Handle。
  • ON 是 Text 组件,起名 ON。
  • OFF 是 Text 组件,起名 OFF。
  • Button 是 Button 组件,起名 ToggleButton。

我们现在 Screen 是现在这样。 image.png

要把所有的组件组合起来,所以需要一些资源文件,在项目中你都可以得到这些资源文件,首先是背景,我这里叫 Toggle_bg,大概是这个样子。 Toggle_bg 其次是我的滑块背景,起名 Handle,大概是这个样子。 Handle 放进 Unity 项目的时候要做这样的处理,这样做 Slice 的属性设置的时候,就不会不会出现圆角的拉伸情况,新技能赶紧 Get。 image.png 将我们的格式编程 Sprite,选择 Sprite Editor。 image.png 这样处理以后,无论你怎么拉伸就只会拉伸绿色框框内部的部分。 当然 Toggle_bg做相同处理,我把参数放在下面。 image.png 两个其实很像~~。

制作我们的 Toggle

ToggleBg 参数如下图: image.png Handle 参数如下图: image.png ON 参数如下图: image.png OFF 参数如下图: image.png **注意:**ON 与 OFF 需要添加 Canvas Group,如果你想让我们 Toggle 更 Nice 的话。(调整透明度) Button 参数如下图: image.png OnClick 的函数等下说,如果你上面的步骤做好之后,你会得到一个这个。 image.png 是不是很棒呢?那我们赶紧让他动起来。

编写 ToggleController 脚本

给 NiceToggle 添加脚本,取名 ToggleController。 image.png 编写如下代码:

using System.Collections;
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class ToggleController : MonoBehaviour
{
    public bool isOn;
    public bool isEnable = true;

    public Color onColorBg;
    public Color offColorBg;
    public Color NoEnableBg;

    public Image toggleBgImage;
    public RectTransform toggle;

    public GameObject handle;
    private RectTransform handleTransform;


    public Button SwitchButton;

    private float handleSize;
    private float onPosX;
    private float offPosX;

    public float handleOffset;

    public GameObject onIcon;
    public GameObject offIcon;


    public float speed;
    static float t = 0.0f;

    private bool switching = false;


    void Awake()
    {
        handleTransform = handle.GetComponent<RectTransform>();
        RectTransform handleRect = handle.GetComponent<RectTransform>();
        handleSize = handleRect.sizeDelta.x;
        float toggleSizeX = toggle.sizeDelta.x;
        onPosX = (toggleSizeX / 2) - (handleSize / 2) - handleOffset;
        offPosX = onPosX * -1;
    }

    void Start()
    {
        if (isOn)
        {
            toggleBgImage.color = onColorBg;
            handleTransform.localPosition = new Vector3(onPosX, 0f, 0f);
            onIcon.gameObject.SetActive(true);
            offIcon.gameObject.SetActive(false);
            DOTweenTransparency(onIcon, 0f, 1f);
            DOTweenTransparency(offIcon, 1f, 0f);
        }
        else
        {
            toggleBgImage.color = offColorBg;
            handleTransform.localPosition = new Vector3(offPosX, 0f, 0f);
            onIcon.gameObject.SetActive(false);
            offIcon.gameObject.SetActive(true);
            DOTweenTransparency(onIcon, 1f, 0f);
            DOTweenTransparency(offIcon, 0f, 1f);
        }
    }

    void Update()
    {
        if (isEnable)
        {
            if (switching)
            {
                Toggle(isOn);
            }
        }
        else
        {
            toggleBgImage.color = NoEnableBg;
            onIcon.gameObject.SetActive(false);
            offIcon.gameObject.SetActive(true);
        }
    }

    public void DoYourStaff()
    {
        Debug.Log(isOn);
    }

    public void Switching()
    {
        if (isEnable)
        {
            switching = true;
        }
    }

    public void Toggle(bool toggleStatus)
    {
        if ((offIcon != null) && ((onIcon != null) && (!onIcon.active || !offIcon.active)))
        {
            onIcon.SetActive(true);
            offIcon.SetActive(true);
        }

        if (toggleStatus)
        {
            StopDOTweenSwitching();
            DOTweenSmoothColor(offColorBg);
            DOTweenTransparency(onIcon, 1f, 0f);
            DOTweenTransparency(offIcon, 0f, 1f);
            DOTweenSmoothMove(onPosX, offPosX);
        }
        else
        {
            StopDOTweenSwitching();
            DOTweenSmoothColor(onColorBg);
            DOTweenTransparency(onIcon, 0f, 1f);
            DOTweenTransparency(offIcon, 1f, 0f);
            DOTweenSmoothMove(offPosX, onPosX);
        }
    }

    void DOTweenSmoothMove(float startPosX, float endPosX)
    {
        DOTween.To(
            () => handleTransform.localPosition,
            x => handleTransform.localPosition = x,
            new Vector3((endPosX - startPosX) / 2, 0f, 0f),
            0.4f
        ).SetEase(Ease.OutQuad);
    }

    void DOTweenSmoothColor(Color endCol)
    {
        DOTween.To(
            () => toggleBgImage.color,
            x => toggleBgImage.color = x,
            endCol,
            0.4f
        ).SetEase(Ease.OutQuad);
    }

    void DOTweenTransparency(GameObject alphaObj, float startAlpha, float endAlpha)
    {
        CanvasGroup alphaVal;
        alphaVal = alphaObj.gameObject.GetComponent<CanvasGroup>();
        DOTween.To(() => alphaVal.alpha, x => alphaVal.alpha = x, endAlpha, 0.4f);
    }

    void StopDOTweenSwitching()
    {
        switching = false;
        switch (isOn)
        {
            case true:
                isOn = false;
                DoYourStaff();
                break;

            case false:
                isOn = true;
                DoYourStaff();
                break;
        }
    }

}

请在 DoYourStaff() 中填写你的业务逻辑,这里使用的 DOTween 的数值线性变化,DOTween 的文档 下一篇文章会单独介绍这个的使用。再把所有的控件挂在到 Controller 上就可以达到文章开头的效果啦,试一下吧。 image.png

About

Perfect Toggle effect

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages