[Unity 3D] UGUI 實(shí)現(xiàn)超贊 Win10 日歷懸停效果

在本文,筆者將教你如何使用 UGUI 和 Shader 實(shí)現(xiàn) Window10 日歷中鼠標(biāo)懸停時(shí)的效果。

預(yù)覽

實(shí)現(xiàn)

1. Shader 實(shí)現(xiàn)

這種動(dòng)效的核心思路是將鼠標(biāo)光標(biāo)的位置傳遞到 shader 中,根據(jù)當(dāng)前像素到光標(biāo)的距離處理該像素的顏色值,這個(gè)動(dòng)作需要拆分分為背景 + 邊框兩部分使用 2 個(gè) Pass 處理。

1.1 Background Pass

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                float dis = distance(_MousePos.xy, i.vertex.xy);
                float4 addColor = _Color;
                addColor.a = saturate(smoothstep(_ColorRadius, 0, dis) - _ColorOffset * sign(col.a-0.1));
                addColor.a =  addColor.a * col.a * _ColorPow;
                return addColor;
            }

1.2 Border Pass

            fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_BorderTex, i.uvBorder);

                float dis = distance(_MousePos.xy, i.vertexBorder.xy);
                
                col = col + sign(col.a) * smoothstep(_ColorRadius, 0, dis) * _Color * _BorderPow;
                return col;
            }

1.3 完整 Shader 代碼

詳見倉(cāng)庫(kù)

2. 腳本實(shí)現(xiàn)

腳本實(shí)現(xiàn)就相當(dāng)?shù)暮?jiǎn)單了,直接實(shí)時(shí)的將鼠標(biāo)位置傳遞到 shader 中即可,當(dāng)然點(diǎn)擊按鈕時(shí)光斑暈開的效果也著實(shí)增添了不少代碼量。

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class UIHoverLight : MonoBehaviour, IPointerDownHandler, IPointerUpHandler
{
    private Material material;
    private void Start()
    {
        var image = GetComponent<Image>();
        //create a new one as we need change color offset later but should not change the others
        material = new(image.material);
        image.material = material;
    }
    private void Update() => material.SetVector("_MousePos", Input.mousePosition);

    Coroutine coroutine;
    void IPointerDownHandler.OnPointerDown(PointerEventData eventData)
    {
        if (null != coroutine)
        {
            StopCoroutine(coroutine);
        }
        if (null != coroutine_hide) 
        {
            StopCoroutine(coroutine_hide);
        }
        coroutine = StartCoroutine(ChangeInnerColorStateAsync(0.3f, true));
    }

    // 當(dāng) _ColorOffset = 0 顯示內(nèi)部顏色
    private IEnumerator ChangeInnerColorStateAsync(float duration, bool show)
    {
        #region Ease
        static float inCubic(float t) => t * t * t;
        static float outCubic(float t) => inCubic(t - 1f) + 1f;
        #endregion

        float time = 0;
        float start = material.GetFloat("_ColorOffset");
        float end = show ? 0 : 0.98f;
        Func<float, float> ease = show ? outCubic : inCubic;
        while (time < duration)
        {
            time += Time.deltaTime;
            var p = ease(time / duration);
            material.SetFloat("_ColorOffset", Mathf.Lerp(start, end, p));
            yield return null;
        }
    }
    Coroutine coroutine_hide;
    void IPointerUpHandler.OnPointerUp(PointerEventData eventData)
    {
        if (null != coroutine_hide)
        {
            StopCoroutine(coroutine_hide);
        }
        coroutine_hide = StartCoroutine(HideInnerColorAsync());
    }
    private IEnumerator HideInnerColorAsync()
    {
        //等待ShowInnerColorAsync結(jié)束
        if (null != coroutine)
        {
            yield return coroutine;
        }
        coroutine_hide = StartCoroutine(ChangeInnerColorStateAsync(0.1f, false));
    }
}

3. 后期特效

為了更好的實(shí)現(xiàn) UI 的輝光效果,我們需要以下 3 個(gè)核心要素:

  • 首先 Canvas 渲染模式使用:Screen Space - Camera 的渲染模式
  • 其次使用 ColorUsageAttribute 聲明了 color 字段用于提供 HDR 設(shè)定。
[SerializeField, ColorUsage(true, true)]
private Color color = Color.white;
  • 最后,安裝 PostProcessing 并啟用 Bloom 效果就好啦~~

結(jié)語(yǔ)

本文也是本著做小抄的目的撰寫,靈感甚至源碼都源自于這里,歡迎在留言區(qū)交流~
本文地址:https://github.com/Bian-Sh/UGUI-Hover-Light-Effect

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容