鼠标点击的涟漪效果(unity&shader)

来源:互联网 发布:ui设计师软件 编辑:程序博客网 时间:2024/05/21 04:43

原文地址:http://www.manew.com/thread-106798-1-1.html

------------------------------------------------------------------------------------------------------

一、前言

    又是一个好久没有更新了,还是因为太忙,生活苟且云云,当然有好的东西还是需要拿出来和大家分享一下的。
    使用的是.5.0版本,惯例,先上效果图,如图所示:该效果是响应每一次鼠标点击时候,在鼠标的点击的位置处产生一个颜色随机的



二、实现方法

1、重点的Shader部分:

    首先,是最难的颜色转换函数,代码:

本帖隐藏的内容

[C#] 纯文本查看 复制代码
//转换颜色的方法fixed3 shift_col(fixed3 RGB, half3 shift){fixed3 RESULT = fixed3(RGB);float VSU = shift.z*shift.y*cos(shift.x*3.14159265 / 180);float VSW = shift.z*shift.y*sin(shift.x*3.14159265 / 180);RESULT.x = (.299*shift.z + .701*VSU + .168*VSW)*RGB.x+ (.587*shift.z - .587*VSU + .330*VSW)*RGB.y+ (.114*shift.z - .114*VSU - .497*VSW)*RGB.z;RESULT.y = (.299*shift.z - .299*VSU - .328*VSW)*RGB.x+ (.587*shift.z + .413*VSU + .035*VSW)*RGB.y+ (.114*shift.z - .114*VSU + .292*VSW)*RGB.z;RESULT.z = (.299*shift.z - .3*VSU + 1.25*VSW)*RGB.x+ (.587*shift.z - .588*VSU - 1.05*VSW)*RGB.y+ (.114*shift.z + .886*VSU - .203*VSW)*RGB.z;return RESULT;}

属性部分为:
[PerRendererData]命令的意思是直接会将该物体的其他材质上的纹理加载进来
[Toggle]命令的意思是一个可以显示在面板上的可勾选项
[C#] 纯文本查看 复制代码
        Properties{[PerRendererData] _MainTex("Sprite Texture", 2D) = "white" {}[HideInInspector]_StartTime("StartTime", Float) = 0_Time("AnimationTime", Range(0.1, 10.0)) = 1.5_Width("Width", Range(0.1, 3.0)) = 0.3_StartWidth("StartWidth", Range(0, 1.0)) = 0.3[Toggle] _isAlpha("isAlpha",Float) = 1[Toggle] _isColorShift("isColorShift",Float) = 1[MaterialToggle] PixelSnap("Pixel snap", Float) = 1}

顶点和片段着色器代码:
[C#] 纯文本查看 复制代码
v2f vert(appdata_base IN){v2f OUT;OUT.vertex = UnityObjectToClipPos(IN.vertex);OUT.texcoord = IN.texcoord;return OUT;}fixed4 frag(v2f IN) : SV_Target        {                fixed4 color = tex2D(_MainTex, IN.texcoord);                float2 pos = (IN.texcoord - float2(0.5,0.5)) * 2; //宽度                float dis = (_Time.y - _StartTime) / _AnimationTime + _StartWidth - length(pos);                //大于最大宽度以及小于0都去掉这部分的像素                if (dis < 0 || dis > _Width)                return fixed4(0,0,0,0);                //如果开启了透明度渐变就让透明度进行插值                float alpha = 1;                if (_isAlpha == 1)                {                        alpha = clamp((_Width - dis) * 3, 0.1, 1.5);                }                fixed3 shiftColor = color;                if (_isColorShift == 1)                {                        half3 shift = half3(_Time.w * 10, 1, 1);                        shiftColor = shift_col(color, shift);                }                return fixed4(shiftColor, color.a * alpha);        }



2、创建波纹预设体

有了Shader之后,创建该Shader的材质球,我一般都会直接选中该Shader,然后右键创建材质,这个材质就直接赋值了这个Shader,并且命名也会和该Shader的名字相关。创建完材质之后,创建一个空物体,并且给这个空物体添加Sprite Renderer属性。将下面的贴图给Sprite Renderer的Sprite。



编写该预设体的控制脚本,代码如下:

[C#] 纯文本查看 复制代码
using System.Collections;using System.Collections.Generic;using UnityEngine;[RequireComponent(typeof(SpriteRenderer))][RequireComponent(typeof(Collider2D))]public class Ripple : MonoBehaviour{    SpriteRenderer mSpriteRenderer;    Collider2D mCircleCollider;    void Awake()    {        mSpriteRenderer = transform.GetComponent<SpriteRenderer>();        mCircleCollider = transform.GetComponent<Collider2D>();    }    void Start()    {        Invoke("unenabledTrigger", 0.05f);        mSpriteRenderer.material.SetFloat("_StartTime", Time.time);        float animationTime = mSpriteRenderer.material.GetFloat("_AnimationTime");        float destroyTime = animationTime;        destroyTime -= mSpriteRenderer.material.GetFloat("_StartWidth") * animationTime;        destroyTime += mSpriteRenderer.material.GetFloat("_Width") * animationTime;        Destroy(transform.gameObject, destroyTime);    }    public void unenabledTrigger()    {        mCircleCollider.enabled = false;    }    public void OnTriggerEnter2D(Collider2D collider)    {    }}


3、最后写一个总控脚本

控制预设体点击创建,代码如下:

[C#] 纯文本查看 复制代码
using System;using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.EventSystems;using UnityEngine.UI;[RequireComponent(typeof(Image))]public class Control : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IDragHandler{    public GameObject prefabRippleEffect;    public void OnDrag(PointerEventData eventData)    {    }    public void OnPointerDown(PointerEventData eventData)    {        CreateNewRipple(eventData.position);    }    public void OnPointerUp(PointerEventData eventData)    {    }    // Use this for initialization    void Start() {    }    // Update is called once per frame    void Update() {        CheckTap();    }    private void CheckTap()    {        foreach (Touch item in Input.touches)        {            if (item.phase == TouchPhase.Began)            {                CreateNewRipple(item.position);            }        }    }    /// <summary>    /// 创建新的波纹    /// </summary>    /// <param name="pos"></param>    private void CreateNewRipple(Vector2 pos)    {        Vector2 worldPos = Camera.main.ScreenToWorldPoint(pos);        GameObject tempNewRipple = Instantiate(prefabRippleEffect, worldPos, Quaternion.identity, transform);    }}