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与模型和粒子特效穿插层级管理 ...
随机推荐
- Shiro学习(16)综合实例
简单的实体关系图 简单数据字典 用户(sys_user) 名称 类型 长度 描述 id bigint 编号 主键 username varchar 100 用户名 password varchar 1 ...
- linux基础知识汇总(四)--ps grep命令
转:http://www.cnblogs.com/allen8807/archive/2010/11/10/1873843.html http://www.cnblogs.com/end/archiv ...
- 一:unittest框架配合selenium工具之CSS_selector定位。
做了自动化测试这么久了,一直没有梳理到元素定位这一块的内容,其重要性不言而喻.趁着周末有时间,梳理一下. 1,通过id定位 driver.find_element_by_css_selector(&q ...
- ORM-Dapper:Dapper列表
ylbtech-ORM-Dapper:Dapper列表 1.返回顶部 1.1. https://dapper-tutorial.net/ 1.2. 2.1. https://www.nuget.org ...
- (转)VS2015基础 指定一个或多个项目执行 - 心少朴的博客
慈心积善融学习,技术愿为有情学.善心速造多好事,前人栽树后乘凉.我今于此写经验,愿见文者得启发. 这个解决方案下,有两个项目, 看到黑体的project了吗?它就是指定执行的项目. 这两 ...
- P2216 [HAOI2007]理想的正方形 (单调队列)
题目链接:P2216 [HAOI2007]理想的正方形 题目描述 有一个 \(a\times b\)的整数组成的矩阵,现请你从中找出一个 \(n\times n\)的正方形区域,使得该区域所有数中的最 ...
- 2017 ICPC Asia Urumqi A.coins (概率DP + 期望)
题目链接:Coins Description Alice and Bob are playing a simple game. They line up a row of nn identical c ...
- LeetCode 复制带随机指针的链表
题目链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer/ 题目大意 略. 分析 空间复杂度 O(1) 的做法非常开拓思维 ...
- 剑指offer——51丑数
题目描述 把只包含质因子2.3和5的数称作丑数(Ugly Number).例如6.8都是丑数,但14不是,因为它包含质因子7. 习惯上我们把1当做是第一个丑数.求按从小到大的顺序的第N个丑数. / ...
- firewall防火墙配置
获取所有zone firewall-cmd --list-all-zones 重启服务 firewall-cmd --complete-reload 名词解释 在具体介绍zone之前学生先给大家介绍几 ...