刚好这几天有朋友问我,我也刚好整理一下。
1.先说非运行时,AssetStore有一个叫Particle Scaler的插件,非常好用。但是很遗憾它运行时不能用。
2.再说运行时,就是让transform的scale可以控制粒子的缩放,如果设置-1就是粒子镜像。
首先,把unity的shader下载下来。http://unity3d.com/cn/get-unity/download/archive 找到所有Particle开头的shader,也就是粒子特效用的。
下面我随便改一个shader,其他的shader修改方法原理一样。 注:shader 中 ”//—Add—“ 就是我修改的内容
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
Shader "Particles/Additive" { Properties { _TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5) _MainTex ("Particle Texture", 2D) = "white" {} _InvFade ("Soft Particles Factor", Range(0.01,3.0)) = 1.0 //----------------------add------------------------------ _Position ("Position", Vector) = (0,0,0,0) _Scale ("Scale", Vector) = (1,1,1,1) //----------------------add------------------------------ } 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; struct appdata_t { float4 vertex : POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; }; struct v2f { float4 vertex : SV_POSITION; fixed4 color : COLOR; float2 texcoord : TEXCOORD0; #ifdef SOFTPARTICLES_ON float4 projPos : TEXCOORD1; #endif }; float4 _MainTex_ST; //----------------------add------------------------------ float4 _Position; float4 _Scale; //----------------------add------------------------------ v2f vert (appdata_t v) { v2f o; //----------------------add------------------------------ float4 objV = mul(UNITY_MATRIX_MV, v.vertex); objV.xyz -= _Position; objV.xyz = float3(_Scale.x * objV.x, _Scale.y * objV.y, _Scale.z * objV.z); objV.xyz += _Position; o.vertex = mul(UNITY_MATRIX_P, objV); //----------------------add------------------------------ //o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); #ifdef SOFTPARTICLES_ON o.projPos = ComputeScreenPos (o.vertex); COMPUTE_EYEDEPTH(o.projPos.z); #endif o.color = v.color; o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex); return o; } sampler2D_float _CameraDepthTexture; float _InvFade; fixed4 frag (v2f i) : SV_Target { #ifdef SOFTPARTICLES_ON float sceneZ = LinearEyeDepth (SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(i.projPos))); float partZ = i.projPos.z; float fade = saturate (_InvFade * (sceneZ-partZ)); i.color.a *= fade; #endif return 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord); } ENDCG } } } } |
接着给需要缩放或者镜像的粒子挂上这一条脚本。利用OnWillRenderObject方法,将粒子的缩放以及坐标传进shader中去。
1 2 3 4 5 6 7 8 9 10 11 |
using UnityEngine; using System.Collections; public class ParticleScaler : MonoBehaviour { void OnWillRenderObject(){ renderer.material.SetVector("_Position",Camera.current.worldToCameraMatrix.MultiplyPoint(transform.root.position)); renderer.material.SetVector("_Scale",transform.lossyScale); } } |
OK.这样粒子就完成了镜像。。 编辑器中快改一改transform的scale的值看看效果吧。
工程代码:http://pan.baidu.com/s/1i34B7Dj
如果你还有更好的办法来做粒子镜像或者旋转,欢迎在下面留言。谢谢~祝大家学习愉快~
感谢楼下好友的补充。
如果特效层级多,旋转嵌套复杂,如果只用lossyScale是不正确的。
应该保持特效层级中的scale为1,1,1然后修改以上脚本:
GetComponent().material.SetVector(“_Scale”, new Vector3(transform.localScale.x * (transform.lossyScale.x < 0 ? -1.0f : 1.0f), transform.localScale.y * (transform.lossyScale.y < 0 ? -1.0f : 1.0f), transform.localScale.z * (transform.lossyScale.z < 0 ? -1.0f : 1.0f)));
- 本文固定链接: https://www.xuanyusong.com/archives/3486
- 转载请注明: 雨松MOMO 于 雨松MOMO程序研究院 发表
5.3版本后粒子异步渲染,导致OnWillRenderObject函数修改*不一定*能反应到粒子上了,该方法已废
5.3以后直接改scale就可以了
请问这个方案 还能用吗
可以用, 我们还在用呢。 只需要把核心代码写在你的新版本shader中就行了。
好的,非常感谢
改了shader之后,把这些shader 放到项目中来是吧? 然后直接改特效 prefab的 localscale吗?
momo 大神,你好,请问 改好shader之后,直接把改好的shader 放到项目中是吧? 然后怎么直接改变 特效prefab 的 localscale 吗 谢谢!
unity版本 是2017
感谢你的分享。请问修改镜像的_InvFade应该怎么做呢? 试了一点效果都没有。_InvFade在镜子里面的值是最大值,并且完全不随调节而变化。
我这个shader是unity 4.6上的, 你下载你的unity对应版本的shader然后把修改的内容放进去。在试试吧。
第十三行的Category{}是什么意思?为什么在子着色器的层级之外声明?
早点看到这方法就好了。。我之前都是直接改粒子效果的各种参数
请问刀光怎么镜像呢
上面的就行, 我们用做的2D格斗游戏, 刀光特效镜像就是用上面的方法,
好的。。我试一下。。先谢谢了。。
试了一下。。3d的格斗游戏刀光貌似不行
3D的不需要镜像啊。。
其实跟用Particle.startSize效果是一样的,可以GetComponentsInChildren()拿出来,修改startsize即可,不过unity4以上版本,模块数据并不开放,所以如果美术使用了模块数据的话,就无法修改了,不知道如何解决,看了下Particle Scaler就是用的unityeditor下的SerializedObject获取模块数据,但是这玩意只能在编辑器里玩玩。。。
momo,你好,请问下skinnedmesh合并以后的模型为什么修改缩放没有效果? 如何才能修改缩放以后的模型?
unity5.1 里,不能用啊
没问题啊。 可以用。。。
报错了Assets/resources/script/ParticleScaler.cs(8,17): error CS0411: The type arguments for method `UnityEngine.Component.GetComponent()’ cannot be inferred from the usage. Try specifying the type arguments explicitly
如果是mobile下的粒子shader该怎么改?
一样的, 就这几个地方。。。
如果特效层级多,旋转嵌套复杂,如果只用lossyScale是不正确的。应该保持特效层级中的scale为1,1,1然后修改以上脚本:GetComponent().material.SetVector(“_Scale”, new Vector3(transform.localScale.x * (transform.lossyScale.x < 0 ? -1.0f : 1.0f), transform.localScale.y * (transform.lossyScale.y < 0 ? -1.0f : 1.0f), transform.localScale.z * (transform.lossyScale.z < 0 ? -1.0f : 1.0f)));
好像如果这个particle在某个particle下面,并且旋转不一样,lossyScale最终的就不对了
最近也在做粒子的缩放和镜像,也坑了很久,谢谢博主的分享。因为我的功能目前暂时只会在编辑器里使用,所以目前运行使还是使用Particle Scaler配合修改y旋转来实现,但是会有一些细节问题。之后试试博主提供的方式 多谢
镜像一般都是做横版动作类游戏。。
差不多的 要做镜像和任意尺寸的缩放所以很麻烦
雨松大神,我最近在研究unity的性能优化,http://matrix.unity3d.com/main.html,这个Unity新推出的功能不知道你有没有用过我想咨询下,你知道他这个是怎么实现的吗,我们可以自己实现类似的吗?
自己就是看profiler 。。。
嗯,就是想做一个类似profiler的功能,但是profiler貌似不能导出性能数据,所以无法自动分析,所以想能够自己获得这些性能数据
非常赞,大神说没有西安的粉丝,我就是啊,沙发一记
呵呵。。