原文地址: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);
}
}