将Particle转成UGUI

news/2024/11/30 11:55:50/文章来源:https://www.cnblogs.com/gangtie/p/18578242

unity官方论坛看到的一个解决方案,可以将Particle直接转换成CanvasRenderer元素显示。
新建一个UIParticleSystem.cs脚本,将以下代码复制进去:

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;[ExecuteInEditMode]
[RequireComponent(typeof(CanvasRenderer))]
[RequireComponent(typeof(ParticleSystem))]
public class UIParticleSystem : MaskableGraphic
{public Texture particleTexture;public Sprite particleSprite;private Transform _transform;private ParticleSystem _particleSystem;private ParticleSystem.Particle[] _particles;private UIVertex[] _quad = new UIVertex[4];private Vector4 _uv = Vector4.zero;private ParticleSystem.TextureSheetAnimationModule _textureSheetAnimation;private int _textureSheetAnimationFrames;private Vector2 _textureSheedAnimationFrameSize;public override Texture mainTexture{get{if (particleTexture){return particleTexture;}if (particleSprite){return particleSprite.texture;}return null;}}protected bool Initialize(){// initialize membersif (_transform == null){_transform = transform;}// prepare particle systemParticleSystemRenderer renderer = GetComponent<ParticleSystemRenderer>();bool setParticleSystemMaterial = false;if (_particleSystem == null){_particleSystem = GetComponent<ParticleSystem>();if (_particleSystem == null){return false;}// get current particle textureif (renderer == null){renderer = _particleSystem.gameObject.AddComponent<ParticleSystemRenderer>();}Material currentMaterial = renderer.sharedMaterial;if (currentMaterial && currentMaterial.HasProperty("_MainTex")){particleTexture = currentMaterial.mainTexture;}// automatically set scaling_particleSystem.scalingMode = ParticleSystemScalingMode.Local;_particles = null;setParticleSystemMaterial = true;}else{if (Application.isPlaying){setParticleSystemMaterial = (renderer.material == null);}
#if UNITY_EDITORelse{setParticleSystemMaterial = (renderer.sharedMaterial == null);}
#endif}// automatically set material to UI/Particles/Hidden shader, and get previous textureif (setParticleSystemMaterial){Material material = new Material(Shader.Find("UI/Particles/Hidden"));if (Application.isPlaying){renderer.material = material;}
#if UNITY_EDITORelse{material.hideFlags = HideFlags.DontSave;renderer.sharedMaterial = material;}
#endif}// prepare particles arrayif (_particles == null){_particles = new ParticleSystem.Particle[_particleSystem.maxParticles];}// prepare uvsif (particleTexture){_uv = new Vector4(0, 0, 1, 1);}else if (particleSprite){_uv = UnityEngine.Sprites.DataUtility.GetOuterUV(particleSprite);}// prepare texture sheet animation_textureSheetAnimation = _particleSystem.textureSheetAnimation;_textureSheetAnimationFrames = 0;_textureSheedAnimationFrameSize = Vector2.zero;if (_textureSheetAnimation.enabled){_textureSheetAnimationFrames = _textureSheetAnimation.numTilesX * _textureSheetAnimation.numTilesY;_textureSheedAnimationFrameSize = new Vector2(1f / _textureSheetAnimation.numTilesX, 1f / _textureSheetAnimation.numTilesY);}return true;}protected override void Awake(){base.Awake();if (!Initialize()){enabled = false;}}protected override void OnPopulateMesh(VertexHelper vh){
#if UNITY_EDITORif (!Application.isPlaying){if (!Initialize()){return;}}
#endif// prepare verticesvh.Clear();if (!gameObject.activeInHierarchy){return;}// iterate through current particlesint count = _particleSystem.GetParticles(_particles);for (int i = 0; i < count; ++i){ParticleSystem.Particle particle = _particles[i];// get particle propertiesVector2 position = (_particleSystem.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position));float rotation = -particle.rotation * Mathf.Deg2Rad;float rotation90 = rotation + Mathf.PI / 2;Color32 color = particle.GetCurrentColor(_particleSystem);float size = particle.GetCurrentSize(_particleSystem) * 0.5f;// apply scaleif (_particleSystem.scalingMode == ParticleSystemScalingMode.Shape){position /= canvas.scaleFactor;}// apply texture sheet animationVector4 particleUV = _uv;if (_textureSheetAnimation.enabled){float frameProgress = 1 - (particle.lifetime / particle.startLifetime);//                float frameProgress = textureSheetAnimation.frameOverTime.curveMin.Evaluate(1 - (particle.lifetime / particle.startLifetime)); // TODO - once Unity allows MinMaxCurve readingframeProgress = Mathf.Repeat(frameProgress * _textureSheetAnimation.cycleCount, 1);int frame = 0;switch (_textureSheetAnimation.animation){case ParticleSystemAnimationType.WholeSheet:frame = Mathf.FloorToInt(frameProgress * _textureSheetAnimationFrames);break;case ParticleSystemAnimationType.SingleRow:frame = Mathf.FloorToInt(frameProgress * _textureSheetAnimation.numTilesX);int row = _textureSheetAnimation.rowIndex;//                    if (textureSheetAnimation.useRandomRow) { // FIXME - is this handled internally by rowIndex?//                        row = Random.Range(0, textureSheetAnimation.numTilesY, using: particle.randomSeed);//                    }frame += row * _textureSheetAnimation.numTilesX;break;}frame %= _textureSheetAnimationFrames;particleUV.x = (frame % _textureSheetAnimation.numTilesX) * _textureSheedAnimationFrameSize.x;particleUV.y = Mathf.FloorToInt(frame / _textureSheetAnimation.numTilesX) * _textureSheedAnimationFrameSize.y;particleUV.z = particleUV.x + _textureSheedAnimationFrameSize.x;particleUV.w = particleUV.y + _textureSheedAnimationFrameSize.y;}_quad[0] = UIVertex.simpleVert;_quad[0].color = color;_quad[0].uv0 = new Vector2(particleUV.x, particleUV.y);_quad[1] = UIVertex.simpleVert;_quad[1].color = color;_quad[1].uv0 = new Vector2(particleUV.x, particleUV.w);_quad[2] = UIVertex.simpleVert;_quad[2].color = color;_quad[2].uv0 = new Vector2(particleUV.z, particleUV.w);_quad[3] = UIVertex.simpleVert;_quad[3].color = color;_quad[3].uv0 = new Vector2(particleUV.z, particleUV.y);if (rotation == 0){// no rotationVector2 corner1 = new Vector2(position.x - size, position.y - size);Vector2 corner2 = new Vector2(position.x + size, position.y + size);_quad[0].position = new Vector2(corner1.x, corner1.y);_quad[1].position = new Vector2(corner1.x, corner2.y);_quad[2].position = new Vector2(corner2.x, corner2.y);_quad[3].position = new Vector2(corner2.x, corner1.y);}else{// apply rotationVector2 right = new Vector2(Mathf.Cos(rotation), Mathf.Sin(rotation)) * size;Vector2 up = new Vector2(Mathf.Cos(rotation90), Mathf.Sin(rotation90)) * size;_quad[0].position = position - right - up;_quad[1].position = position - right + up;_quad[2].position = position + right + up;_quad[3].position = position + right - up;}vh.AddUIVertexQuad(_quad);}}void Update(){if (Application.isPlaying){// unscaled animation within UI_particleSystem.Simulate(Time.unscaledDeltaTime, false, false);SetAllDirty();}}#if UNITY_EDITORvoid LateUpdate(){if (!Application.isPlaying){SetAllDirty();}}
#endif}

  脚本依赖ParticleSystem控件,只能挂载在Paricle物体上。新建一个ParticleSystem将脚本拖上去就能用了!

https://blog.csdn.net/dark00800/article/details/73729947

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/844091.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CV总结之边缘检测

边缘检测 常见算子 边缘检测是图像处理和计算机视觉中的一个基本任务,目的是识别图像中物体的边界。边缘是图像中亮度变化显著的区域,通常标志着物体、表面或形状的边界。边缘检测对于后续的图像分析任务,如特征提取、目标识别和图像分割等,都是非常重要的。 常见边缘检测算…

C# mvc +axios + web api + javascript

2024年,是Insus.NET生命中转折的一年,许久没有更新博客了。许多网友在通讯或邮件私聊,希望在博客上更新内容,分享一些技能与通用的博文。回归正题,在C# mvc使用javascript axios访问web api。 在ms sql server创建数据表 存储过程... C# MVC程序与数据库交互,创建entit…

cron: 如何使用Cron表达式配置定时任务

Cron表达式用于设置定时任务,无论是在Linux的Crontab中,还是在各种语言开发的程序中都有应用,它提供了一种强大而灵活的方法来设定定时任务。 Cron表达式语法 Cron表达式是一种字符串格式,标准的Cron表达式是由五部分组成,分别表示,分钟、小时、日期、月份和星期几。这个…

[C++][MSVC][Error] 检测到 RuntimeLibrary 的不匹配项: 值 MT_StaticRelease 不匹配值 MD_DynamicRelease

1 简介 本文将介绍在 C++ 编程中使用 MSVC 编译器时可能遇到的错误:检测到 RuntimeLibrary 的不匹配项:值 MT_StaticRelease 不匹配值 MD_DynamicRelease。该错误通常是由于编译器和链接器之间的设置不一致引起的。 2 VisualStudio环境 在 MSVC 工程上右键->属性,找到配置…

ChatRoom pg walkthrough Intermediate

NMAP ┌──(root㉿kali)-[~/lab] └─# nmap -p- -A 192.168.189.110 Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-11-30 00:22 UTC Nmap scan report for 192.168.189.110 Host is up (0.073s latency). Not shown: 65533 filtered tcp ports (no-response) PORT …

vxe-table 树形表格的用法详解

vxe-table 树形表格的使用,支持多种数据结构,可以是带有父子结构的数组,也可以带有层级结构的嵌套数据。 官网:https://vxetable.cn Gitee 带有父子结构的平级数据 只需要带有父子结构的平级数据,例如:id 和 parentId,字段名可以任意设置。对于保存到数据库的平级数据非…

电动车头盔穿戴检测方案

电动车头盔穿戴检测方案的核心在于利用现场监控摄像头捕捉道路上骑电动车、三轮车等骑行者的状态,电动车头盔穿戴检测方案通过深度学习算法自动识别骑行者是否佩戴了安全头盔。在实施过程中,监控摄像头会持续捕捉路面情况,并将图像数据传输至后端服务器(也可以前端分析,本…

滑坡监测识别摄像头

滑坡监测识别摄像头安装在潜在滑坡区域,滑坡监测识别摄像头通过捕捉实时图像,对这些图像进行深度分析,识别出可能的滑坡迹象。一旦系统检测到异常,它将立即发出预警信号,通知相关部门采取紧急措施,从而减少灾害带来的损失。滑坡监测识别摄像头的智能预警系统,不仅提高了…

人员跌倒检测摄像头

人员跌倒检测摄像头的核心在于其搭载的深度学习算法,人员跌倒检测摄像头采用了先进的YOLOX结合OpenCV,能够高效地对视频流进行实时分析和处理,当摄像头检测到有人跌倒时,它会自动对跌倒者进行抓拍,并将当时的图像传输到管理中心。这一过程无需人工干预,大大提高了响应速度…

深度学习发展历史

https://www.bookstack.cn/read/paddlepaddle-tutorials/spilt.3.3d52d8126c99cb7b.md 作者:太一吾鱼水 宣言:在此记录自己学习过程中的心得体会,同时积累经验,不断提高自己! 声明:博客写的比较乱,主要是自己看的。如果能对别人有帮助当然更好,不喜勿喷! …

Latex添加一条水平线——overleaf可以用

https://blog.csdn.net/qq_46753404/article/details/118083320 效果如下:添加水平线语法 {\noindent} \rule[-10pt]{17.5cm}{0.05em}\\ {\noindent} 表示取消缩进 \rule[水平高度]{长度}{粗细}