Unity NGUI 多个UIPanel对粒子的剪裁
之前写过一篇单个 UIPanel 对粒子的裁剪,地址是:https://www.cnblogs.com/jietian331/p/5075487.html
但项目中有时会遇到多个UIPanel,如下面问题,UISprite 被剪裁了,但粒子未被剪裁:

转载请注明出处:https://www.cnblogs.com/jietian331/p/10938837.html
这时解决问题的思路是,找出所有的有剪裁功能的 UIPanel,并求出它们剪裁区域的交集然后传到shader中,效果如下:

代码如下:
using System.Collections.Generic;
using UnityEngine; namespace Modules.UI
{
// 对子节点下所有的粒子和模型进行剪裁,且支持多个 UIPanel
public class EffectClip : MonoBehaviour
{
List<Material> m_materials;
List<UIPanel> m_uiPanels;
UIRoot m_uiRoot; #region Properties UIRoot ObjUIRoot
{
get
{
if (!m_uiRoot)
m_uiRoot = GetComponentInParent<UIRoot>();
return m_uiRoot;
}
} // 找到所有粒子,模型的material
List<Material> Materials
{
get
{
if (m_materials == null)
{
m_materials = new List<Material>(); // particle system 的剪裁
var particleSystems = GetComponentsInChildren<ParticleSystem>();
for (int i = , j = particleSystems.Length; i < j; i++)
{
var ps = particleSystems[i];
var mat = ps.GetComponent<Renderer>().material;
string shaderName = mat.shader.name + ""; // 所用shader,重写一份带剪裁功能的
Shader shader = Shader.Find(shaderName);
if (shader)
{
m_materials.Add(mat);
mat.shader = shader;
}
else
{
Debug.LogError("Shader not found, name: " + shaderName);
}
} // mesh 的剪裁
var renders = GetComponentsInChildren<MeshRenderer>();
for (int i = , j = renders.Length; i < j; i++)
{
var ps = renders[i];
var mat = ps.material;
string shaderName = mat.shader.name + ""; // 所用shader,重写一份带剪裁功能的
Shader shader = Shader.Find(shaderName);
if (shader)
{
m_materials.Add(mat);
mat.shader = shader;
}
else
{
Debug.LogError("Shader not found, name: " + shaderName);
}
}
}
return m_materials;
}
} List<UIPanel> Panels
{
get
{
if (m_uiPanels == null)
{
// 获取所有开启剪裁的 UIPanel
m_uiPanels = new List<UIPanel>();
UIPanel[] panels = GetComponentsInParent<UIPanel>();
for (int i = ; i < panels.Length; i++)
{
UIPanel p = panels[i];
if (p && p.clipping == UIDrawCall.Clipping.SoftClip)
{
m_uiPanels.Add(p);
}
}
}
return m_uiPanels;
}
} #endregion void Update()
{
var mats = Materials;
if (mats != null && mats.Count > )
{
for (int i = ; i < m_materials.Count; i++)
{
Vector4 area = CalcClipArea();
m_materials[i].SetVector("_Area", area);
}
}
} // 整合所有 UIPanel 的剪裁区域
Vector4 CalcClipArea()
{
var panels = Panels;
float x = float.MinValue, y = float.MinValue, z = float.MaxValue, w = float.MaxValue; // 求所有 UIPanel 剪裁区域的交集
for (int i = ; i < panels.Count; i++)
{
UIPanel p = panels[i];
Vector4 area = CalcClipArea(p); // 求交集啊
if (area.x > x)
x = area.x;
if (area.y > y)
y = area.y;
if (area.z < z)
z = area.z;
if (area.w < w)
w = area.w;
} return new Vector4(x, y, z, w);
} // 计算单个 UIPanel 的剪裁区域
Vector4 CalcClipArea(UIPanel p)
{
float h = ;
float temp = h / ObjUIRoot.activeHeight;
Vector3 offsetV3 = new Vector3()
{
x = p.clipOffset.x * temp,
y = p.clipOffset.y * temp,
};
Vector3 worldPos = p.transform.position + offsetV3;
Vector4 clipRegion = p.finalClipRegion;
Vector4 nguiArea = new Vector4()
{
x = -clipRegion.z / ,
y = -clipRegion.w / ,
z = clipRegion.z / ,
w = clipRegion.w /
}; return new Vector4()
{
x = worldPos.x + nguiArea.x * temp,
y = worldPos.y + nguiArea.y * temp,
z = worldPos.x + nguiArea.z * temp,
w = worldPos.y + nguiArea.w * temp
};
} }
}
EffectClip
Unity NGUI 多个UIPanel对粒子的剪裁的更多相关文章
- Unity NGUI 粒子的排序
Unity NGUI系统中是没有对粒子进行排序的,如: 怎么解决这个问题呢? 思路是把粒子的渲染层级,相对于UI组件的层级进行一个偏移. 解决后的效果如下: 代码如下: using System.Co ...
- unity NGUI点击消息不传入到场景中去
unity NGUI点击消息不传入到场景中去 1.今天遇到的问题是点击NGUI的按钮,场景中也相应了这个消息 解决的办法是在场景中需要互动的时候,也就是在update中进行判断 是否是点击了NGUI按 ...
- Unity NGUI 网络斗地主 -发牌 脚本交互
Unity NGUI 网络斗地主 -发牌 脚本交互 @By 灰太龙 Unity4.2.1f4 NGUI 3.0.4 本篇说的问题是脚本与控件的交互! 现在对界面进行了改进,先看副图! 1.制作发牌效果 ...
- Unity NGUI 网络斗地主 -制作图集 Atlas
Unity NGUI 网络斗地主 -制作图集 Atlas by @杨海龙 开发环境 Win7+Unity4.2.1f4+NGUI 3.0.4版本 这一节告诉大家如何制作(图集)Atlas! 1.首 ...
- Unity NGUI 网络斗地主 -界面制作
Unity NGUI 网络斗地主 -界面制作 源文件在群(63438968群共享!) @灰太龙 这一节说一下NGUI的界面摆放,并且教会大家使用NGUI的自适应功能! 在这里感谢@Gamer,是他给我 ...
- Unity NGUI 3.0.4版本 制作网络版斗地主
Unity NGUI 3.0.4版本 @by 灰太龙 开发环境 Win7旗舰版 Unity 4.2.1f4 本文就写个开门篇,告诉大家怎么用NGUI,第一步导入NGUI 3.0.4版本! 1.启动U ...
- BMFont中文字体图集制作的方法~(for unity ngui)
BMFont中文字体图集制作的方法~(for unity ngui) 好吧~似乎这个问题困扰了很多人,游戏开始中文化是个不错的事儿啊,这里我就做下说明,如何制作中文字体图集~ 这里的字库图集的制作更多 ...
- Unity NGUI UIPanel下对粒子的剪裁
使用 unity 做游戏开发时,有时需要在scroll view下使用粒子,但粒子是不会被 UIPanel 所裁剪的,本人提供了脚本 ParticleSystemClipper,用来处理这种情况.思路 ...
- Unity NGUI和UGUI与模型、特效的层级关系
目录 1.介绍两大UI插件NGUI和UGUI 2.unity渲染顺序控制方式 3.NGUI的控制 4.UGUI的控制 5.模型深度的控制 6.粒子特效深度控制 7.NGUI与模型和粒子特效穿插层级管理 ...
随机推荐
- MySQL常规操作以及问题
背景 作为一个前端,偶尔搞下后端 要熟悉 SQL 操作,但是一段时间不用 会大部分忘记,之后又要重新查资料 所以自己整理一遍经常用到的 SQL 操作 和使用过程遇到的问题,方便自己快速查阅 一.安装 ...
- BZOJ 1303: [CQOI2009]中位数图(思路题)
传送门 解题思路 比较好想的思路题.首先肯定要把原序列转化一下,大于\(k\)的变成\(1\),小于\(k\)的变成\(-1\),然后求一个前缀和,还要用\(cnt[]\)记录一下前缀和每个数出现了几 ...
- LInux多线程编程----线程属性pthread_attr_t
1.每个POSIX线程有一个相连的属性对象来表示属性.线程属性对象的类型是pthread_attr_t,pthread_attr_t 在文件/usr/include/bits/pthreadtypes ...
- java求两个数中的大数
java求两个数中的大数 java中的max函数在Math中 应用如下: int a=34: int b=45: int ans=Math.max(34,45); 那么ans的值就是45.
- docker集群故障迁移
docker swarm 故障时候镜像迁移(无法添加新节点的时候)生产docker集群出现了故障,无法正常添加删除节点.在这样的情况下只能想办法把故障集群的镜像迁移到新的docker集群当中.将发生故 ...
- 【转】java使用java.lang.management监视和管理 Java 虚拟机
原文地址:https://blog.csdn.net/zhongweijian/article/details/7619383 软件包 java.lang.management 提供管理接口,用于监视 ...
- git clone后切换分支,和远端的不一样。
原因 git clone后再master分支,切换后到了别的分支,分支里面的文件目录是不一样的,导致出现错误. 解决 删除原来的全部文件 git pull 可是git pull报错, git匹配的文件 ...
- ffs, fls
linux内核中的宏ffs(x) linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ...
- 拾遗:编译安装 vim
在非 Gentoo/Funtoo 系的 Linux 发行版上,软件仓库里的 vim 包可能没有加入 python 特性支持,会造成部分插件无法正常使用 一.下载 vim 源码包 ftp://ftp.v ...
- EM相关两个算法 k-mean算法和混合高斯模型
转自http://www.cnblogs.com/jerrylead/archive/2011/04/06/2006924.html http://www.cnblogs.com/jerrylead/ ...