天天看點

Unity之UGUI-特效遮擋問題

一.問題背景

在項目開發過程中,美術和特效時常會給你出一些難題,比如在一張Image上展示一層特效,然後又在這層特效上展示一張Image,這一坨為一個獨立元素,還得在卷軸欄裡滑動,滾動的時候,遮擋邏輯依舊有效。

上圖
           
Unity之UGUI-特效遮擋問題

二.解決方案

方案1.給頂層圖檔添加Canvas,調整OrderinLayer的值

1.調整Canvas的RenderMode為ScreenSpace-Camera,給RenderCamera一個錄影機。

2.調整粒子特效的Renderer的Order inLayer的數值,因為建立的UI和Canvas的SortingLayer為Defalut,OrderinLayer為0。想要粒子特效在底圖之上,其OrderinLayer的值就要比底圖的值大,将粒子特效的OrderinLayer的值調為1。

3.将頂圖的OrderinLayer值調為2,比粒子特效的數值大即可。但是UGUI的ImageImspector面闆是沒有OrderinLayer的屬性的。給Image添加Canvas,調節其OrderinLayer的值。

方案2.将頂層Image替換為SpriteRenderer,調節OrderinLayer的值

1.調整Canvas的RenderMode為ScreenSpace-Camera,給RenderCamera一個錄影機。

2.調整粒子特效的Renderer的Order inLayer的數值,因為建立的UI和Canvas的SortingLayer為Defalut,OrderinLayer為0。想要粒子特效在底圖之上,其OrderinLayer的值就要比底圖的值大,将粒子特效的OrderinLayer的值調為1。

3.将Image改為SpriteRenderer,然後調節OrderinLayer的值

方案3.自制UIMaskMaterial,控制粒子特效的顯示區間

1.調整Canvas的RenderMode為ScreenSpace-Camera,給RenderCamera一個錄影機。

2.調整粒子特效的Renderer的Order inLayer的數值,因為建立的UI和Canvas的SortingLayer為Defalut,OrderinLayer為0。想要粒子特效在底圖之上,其OrderinLayer的值就要比底圖的值大,将粒子特效的OrderinLayer的值調為1。

3.在粒子區間放置一個空Image,添加自制的MaskMaterial材質,然後調整特效的Masking為VisibleInsideMask, 在頂層的圖檔隻需要添加 mask遮罩即可遮擋粒子特效了。

上圖
           
Unity之UGUI-特效遮擋問題
Unity之UGUI-特效遮擋問題
Unity之UGUI-特效遮擋問題
Unity之UGUI-特效遮擋問題
Unity之UGUI-特效遮擋問題
Unity之UGUI-特效遮擋問題
Unity之UGUI-特效遮擋問題

三.代碼

MaskMaterial使用的Shader的腳本為

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "UI/MaskDefault"
{
	Properties
	{
		[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
		_Color ("Tint", Color) = (1,1,1,1)
		
		_StencilComp ("Stencil Comparison", Float) = 8
		_Stencil ("Stencil ID", Float) = 0
		_StencilOp ("Stencil Operation", Float) = 0
		_StencilWriteMask ("Stencil Write Mask", Float) = 255
		_StencilReadMask ("Stencil Read Mask", Float) = 255

		_ColorMask ("Color Mask", Float) = 15

		[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
	}

	SubShader
	{
		Tags
		{ 
			"Queue"="Transparent" 
			"IgnoreProjector"="True" 
			"RenderType"="Transparent" 
			"PreviewType"="Plane"
			"CanUseSpriteAtlas"="True"
		}
		
		

		Cull Off
		Lighting Off
		ZWrite Off
		ZTest [unity_GUIZTestMode]
		Blend SrcAlpha OneMinusSrcAlpha
		ColorMask 0

		Stencil
		{
			Ref 1
			Comp Always
			Pass Replace
		}

		Pass
		{
		CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag

			#include "UnityCG.cginc"
			#include "UnityUI.cginc"

			#pragma multi_compile __ UNITY_UI_ALPHACLIP
			
			struct appdata_t
			{
				float4 vertex   : POSITION;
				float4 color    : COLOR;
				float2 texcoord : TEXCOORD0;
			};

			struct v2f
			{
				float4 vertex   : SV_POSITION;
				fixed4 color    : COLOR;
				half2 texcoord  : TEXCOORD0;
				float4 worldPosition : TEXCOORD1;
			};
			
			fixed4 _Color;
			fixed4 _TextureSampleAdd;
			float4 _ClipRect;

			v2f vert(appdata_t IN)
			{
				v2f OUT;
				OUT.worldPosition = IN.vertex;
				OUT.vertex = UnityObjectToClipPos(OUT.worldPosition);

				OUT.texcoord = IN.texcoord;
				
				#ifdef UNITY_HALF_TEXEL_OFFSET
				OUT.vertex.xy += (_ScreenParams.zw-1.0)*float2(-1,1);
				#endif
				
				OUT.color = IN.color * _Color;
				return OUT;
			}

			sampler2D _MainTex;

			fixed4 frag(v2f IN) : SV_Target
			{
				half4 color = (tex2D(_MainTex, IN.texcoord) + _TextureSampleAdd) * IN.color;
				
				color.a *= UnityGet2DClipping(IN.worldPosition.xy, _ClipRect);
				
				#ifdef UNITY_UI_ALPHACLIP
				clip (color.a - 0.001);
				#endif

				return color;
			}
		ENDCG
		}
	}
}

           

四.工程項目

連結:https://pan.baidu.com/s/1VByGBqJ7sCjAjkPPkfzW0A

提取碼:h56i

複制這段内容後打開百度網盤手機App,操作更友善哦–來自百度網盤超級會員V4的分享

參考:

UGUI粒子遮罩(UI Mask 遮擋粒子)

UnityShader執行個體09:Stencil Buffer&Stencil Test