UnityNGUIUIPanel下对粒子或自定义Mesh-创新互联

写在开篇:

创新互联主营凤城网站建设的网络公司,主营网站建设方案,成都app开发,凤城h5小程序开发搭建,凤城网站营销推广欢迎凤城等地区企业咨询

  越来越烦那些无脑转发自己不做验证的博主论坛楼主,网上好不容易找到一些资料,结果代码搞下来却是错的,有些确实是因为版本问题太老不兼容,但是有些明显是有问题的,转发前自己试试就知道肯定是不能用的。结果。。。哎。。。真是不想说啥了。

  这次是在小地图中画线画圈,用到了动态绘制Mesh,小地图需要对这些线进行裁切,所以去网上搜了一篇叫做《Unity NGUI UIPanel下对粒子的剪裁》的文章。当然还是感谢一下原作者提供的思路。我这里对这篇文章中涉及到的代码进行了优化改动,使之可以使用。没错!使之可以使用!!!不然没法用啊啊啊啊!!!还有让我最抓狂的一点,就是某些特定分辨率下裁切范围有问题的bug,我也改掉了!!!

  废话不多说了,上代码

CustomUIClipper.cs

using System; using UnityEngine; [RequireComponent(typeof(UIPanel))] public class CustomUIClipper : MonoBehaviour {     const string ShaderName = "Bleach/Particles Additive Area Clip";     const float ClipInterval = 0.5f;     UIPanel m_targetPanel;     Shader m_shader;     void Start()     {         // find panel         m_targetPanel = GetComponent();         if (m_targetPanel == null)             throw new ArgumentNullException("Cann't find the right UIPanel");         if (m_targetPanel.clipping != UIDrawCall.Clipping.SoftClip)             throw new InvalidOperationException("Don't need to clip");         m_shader = Shader.Find(ShaderName);         //if (!IsInvoking("Clip"))         //    InvokeRepeating("Clip", 0, ClipInterval);         Clip();     }     Vector4 CalcClipArea()     {         var clipRegion = m_targetPanel.finalClipRegion;         Vector4 nguiArea = new Vector4()         {             x = clipRegion.x - clipRegion.z / 2,             y = clipRegion.y - clipRegion.w / 2,             z = clipRegion.x + clipRegion.z / 2,             w = clipRegion.y + clipRegion.w / 2         };         var uiRoot = m_targetPanel.root;         var pos = m_targetPanel.transform.position;         float rate1 = (float)Screen.width / (float)Screen.height;         float rate2 = (float)uiRoot.manualWidth / (float)uiRoot.manualHeight;         float h = 2f;         float w = h * rate1;         float tempH = h / uiRoot.manualHeight;         float tempW = w / uiRoot.manualWidth;         float tempRate = Mathf.Max(tempW, tempH);         if (rate1 < rate2)         {             tempRate = Mathf.Min(tempW, tempH);         }         Vector4 result =  new Vector4()         {             x = pos.x + nguiArea.x * tempRate,             y = pos.y + nguiArea.y * tempRate,             z = pos.x + nguiArea.z * tempRate,             w = pos.y + nguiArea.w * tempRate         };         return result;     }     void Clip()     {         Vector4 clipArea = CalcClipArea();         Renderer[] renderers = GetComponentsInChildren();         for (int i = 0; i < renderers.Length; ++i)         {             var mat = renderers[i].material;             if (mat.shader.name != ShaderName)                 mat.shader = m_shader;             mat.SetVector("_Area", clipArea);         }     }     void OnDestroy()     {         //CancelInvoke("Clip");     } }

将这个文件挂载到带有裁切功能的UIPanel上

这个Panel下的粒子或者Mesh使用的shader代码如下:

Shader "Bleach/Particles Additive Area Clip" {     Properties     {         _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)         _MainTex ("Particle Texture", 2D) = "white" {}         _Area ("Area", Vector) = (0,0,1,1)     }     Category     {         Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }         Blend SrcAlpha One         AlphaTest Greater .01         ColorMask RGB         Cull Off         Lighting Off         ZWrite Off         Fog { Color (0,0,0,0) }                  SubShader          {             Pass             {                 CGPROGRAM                 #pragma vertex vert                 #pragma fragment frag                 #pragma multi_compile_particles                 #include "UnityCG.cginc"                 sampler2D _MainTex;                 fixed4 _TintColor;                 float4 _Area;                                  struct appdata_t                 {                     float4 vertex : POSITION;                     fixed4 color : COLOR;                     float2 texcoord : TEXCOORD0;                 };                 struct v2f                 {                     float4 vertex : SV_POSITION;                     fixed4 color : COLOR;                     float2 texcoord : TEXCOORD0;                     float2 worldPos : TEXCOORD1;                 };                                  float4 _MainTex_ST;                 v2f vert (appdata_t v)                 {                     v2f o;                     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);                     o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);                     o.color = v.color;                     o.worldPos = mul(_Object2World, v.vertex).xy;                     return o;                 }                 fixed4 frag (v2f i) : SV_Target                 {                     bool inArea = i.worldPos.x >= _Area.x && i.worldPos.x <= _Area.z && i.worldPos.y >= _Area.y && i.worldPos.y <= _Area.w;                     return inArea? 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord) : fixed4(0,0,0,0);                 }                 ENDCG              }         }         } }

如果有需要对shader做改动的,就用这个为范本进行修改吧

大功告成

  哦对了,我这里进行了优化,如果Panel尺寸不变并且子对象不会动态添加,可以不用进行重复发送裁切数据,请大家根据自己的情况进行代码修改,如果有以上的情况,将Clip函数的Invoke调用注释打开即可

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。


当前文章:UnityNGUIUIPanel下对粒子或自定义Mesh-创新互联
转载来源:http://scyanting.com/article/hopoo.html