方法一:(特效预制体)
新建特效预制体,放在Resources文件夹下
using UnityEngine;
public class ClickEffect : MonoBehaviour {
Vector3 point;
GameObject effectGo;
void Start () {
effectGo = Resources.Load<GameObject>("Prefabs/EffectClick");
}
void Update () {
//点击鼠标特效
if (Input.GetMouseButtonDown(0))
{
point = new Vector3(Input.mousePosition.x,Input.mousePosition.y,4f);//获得鼠标点击点
point = Camera.main.ScreenToWorldPoint(point);//从屏幕空间转换到世界空间
GameObject go = Instantiate(effectGo);//生成特效
go.transform.position = point;
Destroy(go, 0.5f);
}
}
}
方法二:(水波纹效果)shader篇
shader文件
Shader "Unlit/ClickEffect"// Shader中的位置这个最后一个名字要和你创的Shader名字一样
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
float4 _MainTex_TexelSize;
uniform float _distanceFactor; //距离系数
uniform float _timeFactor; //时间系数
uniform float _totalFactor; //sin函数结果系数
uniform float _waveWidth; //波纹宽度
uniform float _curWaveDis; //扩散速度
uniform float4 _startPos; //开始位置
fixed4 frag(v2f_img i) : SV_Target
{
//DX下纹理坐标反向问题
//UNITY_UV_STARTS_AT_TOP总是用1或0定义,Direct3D平台为1,OpenGL平台为0
//在Direct3D中,坐标顶点为零,向下增加
//OpenGL坐标底部为零,向上增加
#if UNITY_UV_STARTS_AT_TOP
if (_MainTex_TexelSize.y < 0)
_startPos.y = 1 - _startPos.y;
#endif
//计算uv到中间点的向量(向外扩,反过来就是向里缩)
float2 dv = _startPos.xy - i.uv;
//按照屏幕长宽比进行缩放
dv = dv * float2(_ScreenParams.x / _ScreenParams.y, 1);
//计算像素点距中点的距离
float dis = sqrt(dv.x * dv.x + dv.y * dv.y);
//用sin函数计算出波形的偏移值factor
//dis在这里都是小于1的,所以我们需要乘以一个比较大的数,比如60,这样就有多个波峰波谷
//sin函数是(-1,1)的值域,我们希望偏移值很小,所以这里我们缩小100倍,据说乘法比较快,so...
float sinFactor = sin(dis * _distanceFactor + _Time.y * _timeFactor) * _totalFactor * 0.01;
//距离当前波纹运动点的距离,如果小于waveWidth才予以保留,否则已经出了波纹范围,factor通过clamp设置为0
float discardFactor = clamp(_waveWidth - abs(_curWaveDis - dis), 0, 1) / _waveWidth;
//归一化
float2 dv1 = normalize(dv);
//计算每个像素uv的偏移值
float2 offset = dv1 * sinFactor * discardFactor;
//像素采样时偏移offset
float2 uv = offset + i.uv;
return tex2D(_MainTex, uv);
}
ENDCG
SubShader
{
Pass
{
ZTest Always
Cull Off
ZWrite Off
Fog{ Mode off }
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
ENDCG
}
}
Fallback off
}
控制文件 (挂到摄像机上)
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//非运行时也出发效果
[ExecuteInEditMode]
public class WaterWave : MonoBehaviour {
//Inspector面板上直接拖入
public Shader shader = null;
private Material _material = null;
//距离系数
public float distanceFactor = 60.0f;
//时间系数
public float timeFactor = -30.0f;
//sin函数结果系数
public float totalFactor = 1.0f;
//波纹宽度
public float waveWidth = 0.3f;
//波纹扩散的速度
public float waveSpeed = 0.3f;
private float waveStartTime;
private Vector4 startPos = new Vector4(0.5f, 0.5f, 0, 0);
//根据Shader生成材质
public Material _Material
{
get
{
if (_material == null)
_material = GenerateMaterial(shader);
return _material;
}
}
//根据shader创建用于屏幕特效的材质
protected Material GenerateMaterial(Shader shader)
{
if (shader == null)
return null;
//需要判断shader是否支持
if (shader.isSupported == false)
return null;
Material material = new Material(shader);
material.hideFlags = HideFlags.DontSave;
if (material)
return material;
return null;
}
void OnRenderImage(RenderTexture source, RenderTexture destination)
{
//计算波纹移动的距离,根据enable到目前的时间*速度求解
float curWaveDistance = (Time.time - waveStartTime) * waveSpeed;
//设置一系列参数
_Material.SetFloat("_distanceFactor", distanceFactor);
_Material.SetFloat("_timeFactor", timeFactor);
_Material.SetFloat("_totalFactor", totalFactor);
_Material.SetFloat("_waveWidth", waveWidth);
_Material.SetFloat("_curWaveDis", curWaveDistance);
_Material.SetVector("_startPos", startPos);
Graphics.Blit(source, destination, _Material);
}
void Update()
{
if (Input.GetMouseButton(0))
{
Vector2 mousePos = Input.mousePosition;
//将mousePos转化为(0,1)区间
startPos = new Vector4(mousePos.x / Screen.width, mousePos.y / Screen.height, 0, 0);
waveStartTime = Time.time;
}
}
}
方法三:燃烧消失特效(需要两个贴图,一张噪点)
Shader "Custom/FireEffect" {
Properties{
_Color("主颜色", Color) = (1,1,1,1) // 主色
_MainTex("模型贴图", 2D) = "white" {} // 主材质
_DissolveText("溶解贴图", 2D) = "white" {} // 溶解贴图
_Tile("溶解贴图的平铺大小", Range(0, 1)) = 1 // 平铺值,设置溶解贴图大小
_Amount("溶解值", Range(0, 1)) = 0.5 // 溶解度
_DissSize("溶解大小", Range(0, 1)) = 0.1 // 溶解范围大小
_DissColor("溶解主色", Color) = (1,1,1,1) // 溶解颜色
_AddColor("叠加色,与主色叠加为开始色[R|G|B>0表示启用]", Color) = (1,1,1,1) // 改色与溶解色融合形成开始色
}
SubShader{
Tags { "RenderType" = "Opaque" }
LOD 200
Cull off
CGPROGRAM
#pragma target 3.0
#pragma surface surf BlinnPhong
sampler2D _MainTex;
sampler2D _DissolveText;
fixed4 _Color; // 主色
half _Tile; // 平铺值
half _Amount; // 溶解度
half _DissSize; // 溶解范围
half4 _DissColor; // 溶解颜色
half4 _AddColor; // 叠加色
// 最终色
static half3 finalColor = float3(1,1,1);
struct Input {
float2 uv_MainTex; // 只需要主材质的UV信息
};
void surf(Input IN, inout SurfaceOutput o) {
// 对主材质进行采样
fixed4 tex = tex2D(_MainTex, IN.uv_MainTex);
// 设置主材质和颜色
o.Albedo = tex.rgb * _Color.rgb;
// 对裁剪材质进行采样,取R色值
float ClipTex = tex2D(_DissolveText, IN.uv_MainTex / _Tile).r;
// 裁剪量 = 裁剪材质R - 外部设置量
float ClipAmount = ClipTex - _Amount;
if (_Amount > 0)
{
// 如果裁剪材质的R色值 < 设置的裁剪值 那么此点将被裁剪
if (ClipAmount < 0)
{
clip(-0.1);
}
// 然后处理没有被裁剪的值
else
{
// 针对没有被裁剪的点,【裁剪量】小于【裁剪大小】的做处理
// 如果设置了叠加色,那么该色为ClipAmount/_DissSize(这样会形成渐变效果)
if (ClipAmount < _DissSize)
{
if (_AddColor.x == 0)
finalColor.x = _DissColor.x;
else
finalColor.x = ClipAmount / _DissSize;
if (_AddColor.y == 0)
finalColor.y = _DissColor.y;
else
finalColor.y = ClipAmount / _DissSize;
if (_AddColor.z == 0)
finalColor.z = _DissColor.z;
else
finalColor.z = ClipAmount / _DissSize;
// 融合
o.Albedo = o.Albedo * finalColor * 2;
}
}
}
o.Alpha = tex.a * _Color.a;
}
ENDCG
}
}
大兄弟,如果文章对您有帮助的话,可不可以点个赞啊~