NGUI中并没有提供特效裁剪的功能,这个需要我们自己实现了。
不过实现起来也容易。
我们先来看一下,NGUI的裁剪原理(这里我就不写了,直接上链接)
https://blog.csdn.net/tkokof1/article/details/52089289
知道裁剪原理之后我们自己就可以仿照NGUI的做法,将panel的裁剪信息传到特效Shader中实现裁剪,你完全可以不参考这种方式自己实现。
这里我只是实现了一个父panel的裁剪,多个panel的话就会出现不正确,不过一般情况下不会出panel之间交叉裁剪。
脚本代码
using UnityEngine;
using System.Collections;
public class UIParticalClip : MonoBehaviour
{
private UIPanel mPanel;
private Renderer[] mSenderers;
private bool mRefresh = false;
void Start()
{
mRefresh = false;
mPanel = gameObject.GetComponentInParent<UIPanel>();
mSenderers = gameObject.GetComponentsInChildren<Renderer>();
if (mPanel != null)
{
mPanel.onClipMove += SetClip;
}
}
void Update()
{
if (mRefresh == false)
{
mRefresh = true;
SetClip(mPanel);
}
}
void SetClip(UIPanel panel)
{
if (panel == null)
{
return;
}
if (mSenderers == null)
{
return;
}
Vector2 soft = panel.clipSoftness;
var panelWorldCorners = panel.worldCorners;
var leftBottom = panelWorldCorners[0];
var rightTop = panelWorldCorners[2];
var center = Vector3.Lerp(leftBottom, rightTop, 0.5f);
var z = rightTop.x - leftBottom.x;
var w = rightTop.y - leftBottom.y;
var cr = new Vector4(center.x, center.y, z * 0.5f, w * 0.5f);
Vector2 sharpness = new Vector2(1000.0f, 1000.0f);
//if (soft.x > 0f) sharpness.x = cr.z / soft.x;
//if (soft.y > 0f) sharpness.y = cr.w / soft.y;
foreach (Renderer render in mSenderers)
{
if (render != null)
{
render.material.SetVector("_ClipRange0", new Vector4(-cr.x / cr.z, -cr.y / cr.w, 1f / cr.z, 1f / cr.w));
render.material.SetVector("_ClipArgs0", new Vector2(sharpness.x, sharpness.y));
}
}
}
}
Shader代码
Shader "Particle/UIParticleClip" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
_MainTex ("Particle Texture", 2D) = "white" {}
_ClipRange0 ("_ClipRange0",Vector) = (0.0, 0.0, 0.0, 0.0)
_ClipArgs0 ("_ClipArgs0",Vector) = (1000.0, 1000.0, 0.0, 0.0)
}
SubShader {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
Blend SrcAlpha One
Fog { Mode off }
ColorMask RGBA
Cull Off Lighting Off ZWrite Off
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_particles
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 _TintColor;
float4 _ClipRange0;
float4 _ClipArgs0;
struct appdata_t {
half4 vertex : POSITION;
fixed4 color : COLOR;
half2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
half3 texcoord : TEXCOORD0;
float2 worldPos : TEXCOORD1;
};
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.color = v.color;
o.texcoord.xy = TRANSFORM_TEX(v.texcoord,_MainTex);
o.texcoord.z = 0;
o.worldPos = v.vertex.xy * _ClipRange0.zw + _ClipRange0.xy;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// Softness factor
float2 factor = (float2(1.0, 1.0) - abs(i.worldPos)) * _ClipArgs0;
fixed4 col = 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord.xy);
col.a *= clamp( min(factor.x, factor.y), 0.0, 1.0);
return col;
}
ENDCG
}
}
}