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与模型和粒子特效穿插层级管理 ...
随机推荐
- 【Flutter学习】基本组件之基本表单组件
一,概述 表单时一个包含表单元素的区域. 表单元素允许用户输入内容,比如文本域,下拉列表,单选框,复选框等.常见的应用场景有:登录,注册,输入信息等. 表单里有两个重要的组件: Form:用来做整个表 ...
- list 链表
#include <list> #include <iostream> using std::list; /* 双向环状链表 //每一个结点 一个数据域 一个前驱指针 一个后驱 ...
- HBase自定义MapReduce
HBase表数据的转移 在Hadoop阶段,我们编写的MR任务分别进程了Mapper和Reducer两个类,而在HBase中我们需要继承的是TableMapper和TableReducer两个类. 目 ...
- JAVA并发工具类---------------(Fork/Join)
Fork/Join 分而治之 将一个大任务分成数个小任务执行,然后将这些小人物执行后的结果进行join汇总: (假设:你要计算1到1000的总和,你可以把它分成1-100,101-200,...... ...
- (转)Openfire 中SASL的认证方式之:PLAIN,DIGEST-MD5,anonymous
转:http://blog.csdn.net/coding_me/article/details/39524137 SASL 的认证方式包括: 1. PLAIN:plain是最简单的机制,但 ...
- mybatis 丢失字段
实体上,如果没写get,记得加上 @Data
- 正则表达式Pattern类的基本用法
public void mailRegex() { // 要验证的字符串 String str = "shiruo.hdp@taobao.com"; // 邮箱验证规则 Strin ...
- Linxu下JMeter进行接口压力测试
****************************************************************************** 本文主要介绍Jmeter脚本如何在Linx ...
- java.io.FileNotFoundException: [WEB-INF/spring-servlet.xml] cannot be opened because it does not exist
今天启动web 项目出现错误提示: java.io.FileNotFoundException: [WEB-INF/spring-servlet.xml] cannot be opened becau ...
- Mybatis Generator 安装(idea+maven)
1.在Intellij IDEA创建maven项目(本过程比较简单,略) 2. 在maven项目的pom.xml 添加mybatis-generator-maven-plugin 插件 <bui ...