当前位置:   article > 正文

UGUI:调整Unity中UI和特效的层级关系(特效穿透问题)_unity中特效显示在image背景上 其他ui元素覆盖在特效上 层级怎么处理

unity中特效显示在image背景上 其他ui元素覆盖在特效上 层级怎么处理

一般情况下,在Unity中添加UI元素,会先添加一个主要的Canvas,游戏中的UI元素都会挂在这个Canvas下。

RenderMode选ScreenSpace Camera,再挂一个UI摄像机。参数如下:

UI Camera的Projection、Size、Clipping Planes影响着UI的渲染。

Camera的参数如下:

关于渲染顺序,这里有篇文章写得挺齐全的:Unity中影响渲染顺序的因素总结

下图是他总结的渲染图:

一般情况下,两个UI位于同一个Canvas中,它们的层级关系只需要注意UI或其父物体在Hierarchy的位置关系即可。如果不在同一个Canvas下,可以修改Canvas的SortOrder。

但是如果是特效和UI,改变Hierarchy的位置不能解决特效穿透问题。

方法一、

给UI和特效加上Canvas,修改Cannvas的SortOrder值。

因为Unity是根据Canvas绘制的,不同的Canvas尽管引用的图集相同,也会增加额外的DrawCall,所以性能消耗可能会增加。

另外也可能引起其他的层级穿透问题,不好控制层级关系。

方法二、

因为方法一踩了很多坑,在网上查找其他的解决方案的时候翻到这个文章,试了一下SpriteRenderer,该方法方法可行。

只是要注意Canvas的scale修改SpriteRenderer的scale。

 Unity UGUI调整UI与粒子特效的显示层级

方法三、

我们也可以修改shader的渲染区域来解决该问题,添加一个脚本MaskExtend,初始化一个裁剪的区域,然后修改特效的shader,使特效在裁剪区域才可以显示。

  1. using UnityEngine;
  2. using System.Collections;
  3. using UnityEngine.UI;
  4. public class MaskExtend : Mask
  5. {
  6. Camera cam;
  7. protected override void Start()
  8. {
  9. base.Start();
  10. ResetShaderMaskClip();
  11. }
  12. public void ResetShaderMaskClip()
  13. {
  14. Vector3[] points = new Vector3[4];
  15. (transform as RectTransform).GetWorldCorners(points);
  16. if (cam == null)
  17. cam = GameObject.Find("Camera").GetComponent<Camera>();
  18. float miniX,miniY,maxX,maxY;
  19. Vector3 scPos = cam.WorldToScreenPoint(points[0]);
  20. miniX = scPos.x;
  21. miniY = scPos.y;
  22. maxX = scPos.x;
  23. maxY = scPos.y;
  24. for (int i = 0; i < points.Length; i++)
  25. {
  26. scPos = cam.WorldToScreenPoint(points[i]);
  27. //取最小xy
  28. miniX = scPos.x < miniX ? scPos.x : miniX;
  29. miniY = scPos.y < miniY ? scPos.y : miniY;
  30. //取最大xy
  31. maxX = scPos.x > maxX ? scPos.x : maxX;
  32. maxY = scPos.y > maxY ? scPos.y : maxY;
  33. }
  34. Vector4 normalize = new Vector4(miniX / Screen.width, miniY / (float)Screen.height, maxX / (float)Screen.width, maxY / (float)Screen.height);
  35. Shader.SetGlobalVector("_MaskClip", normalize);
  36. }
  37. }

添加mask  shader

  1. Shader "Unlit/UIMaskClip" {
  2. Properties{
  3. _MainTex("Texture", 2D) = "white" { }
  4. _TintColor("Color", Color) = (0.5,0.5,0.5,0.5)
  5. _Lighting("Lighting", float) = 1
  6. _CutOut("CutOut", float) = 0.1
  7. //此段可以将 ZWrite 选项暴露在Unity的Inspector中
  8. [Enum(Off, 0, On, 1)] _zWrite("Zwrite", Float) = 0
  9. //此段可以将 Ztest 选项暴露在Unity的Inspector中
  10. [Enum(UnityEngine.Rendering.CompareFunction)] _zTest("ZTest", Float) = 4
  11. //此段可以将 Cull 选项暴露在Unity的Inspector中
  12. [Enum(UnityEngine.Rendering.CullMode)] _cull("Cull Mode", Float) = 2
  13. //此段可以将 Blend 选项暴露在Unity的Inspector中
  14. [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Src Blend Mode", Float) = 5
  15. [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Dst Blend Mode", Float) = 10
  16. [Enum(UnityEngine.Rendering.BlendMode)] _SrcAlphaBlend("Src Alpha Blend Mode", Float) = 1
  17. [Enum(UnityEngine.Rendering.BlendMode)] _DstAlphaBlend("Dst Alpha Blend Mode", Float) = 10
  18. }
  19. SubShader{
  20. //@@@DynamicShaderTagsRepaceStart
  21. Tags {"Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" }
  22. //@@@DynamicShaderTagsRepaceEnd
  23. Pass
  24. {
  25. //面板化
  26. Blend[_SrcBlend][_DstBlend],[_SrcAlphaBlend][_DstAlphaBlend]
  27. Zwrite[_zWrite]
  28. ZTest[_zTest]
  29. Cull[_cull]
  30. //@@@DynamicShaderBlendRepaceStart
  31. //@@@DynamicShaderBlendRepaceEnd
  32. CGPROGRAM
  33. #pragma vertex vert
  34. #pragma fragment frag
  35. #include "UnityCG.cginc"
  36. // #pragma multi_compile CLIP_OFF CLIP_ON
  37. sampler2D _MainTex;
  38. float4 _MainTex_ST;
  39. float _Lighting;
  40. float4 _MaskClip;
  41. struct v2f {
  42. float4 pos : SV_POSITION;
  43. float2 uv : TEXCOORD0;
  44. float4 color : COLOR;
  45. float4 projPos : TEXCOORD2;
  46. }
  47. ;
  48. struct appdata {
  49. float4 vertex : POSITION;
  50. float2 texcoord:TEXCOORD0;
  51. float4 color : COLOR;
  52. }
  53. ;
  54. //顶点函数没什么特别的,和常规一样
  55. v2f vert(appdata v)
  56. {
  57. v2f o;
  58. o.pos = UnityObjectToClipPos(v.vertex);
  59. o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
  60. o.color = v.color;
  61. o.projPos = ComputeScreenPos(o.pos);
  62. return o;
  63. }
  64. fixed4 _TintColor;
  65. float4 frag(v2f i) : COLOR
  66. {
  67. float4 col = tex2D(_MainTex,i.uv);
  68. col = col* _TintColor*i.color;
  69. col.rgb *= _Lighting;
  70. //先clip,再fog 不然会出错
  71. int o;
  72. o = sign(i.projPos.x - _MaskClip.x) + sign(i.projPos.y - _MaskClip.y) + sign(_MaskClip.z - i.projPos.x) + sign(_MaskClip.w - i.projPos.y);
  73. clip(o / 4 - 0.5);
  74. return col;
  75. }
  76. ENDCG
  77. }
  78. }
  79. }

shader的问题,代码是别人给的。如果你有其他好方法的话,欢迎讨论。

参考:

https://blog.csdn.net/qweewqpkn/article/details/79656263

https://www.cnblogs.com/Bright-King/p/9205534.html

https://gameinstitute.qq.com/community/detail/113593

优化:

http://www.manew.com/thread-95049-1-1.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/92979
推荐阅读
相关标签
  

闽ICP备14008679号