customData | 每粒子数据的数组。 |
streamIndex | 要将数据分配到的流。 |
设置自定义每粒子数据流。
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
public class ExampleClass : MonoBehaviour {
private ParticleSystem ps;
private ParticleSystemRenderer psr;
private List<Vector4> customData = new List<Vector4>();
public float minDist = 30.0f;
void Start() {
ps = GetComponent<ParticleSystem>();
psr = GetComponent<ParticleSystemRenderer>();
// emit in a sphere with no speed
var main = ps.main;
main.startSpeedMultiplier = 0.0f;
main.simulationSpace = ParticleSystemSimulationSpace.World; // so our particle positions don't require any extra transformation, to compare with the mouse position
var emission = ps.emission;
emission.rateOverTimeMultiplier = 200.0f;
var shape = ps.shape;
shape.shapeType = ParticleSystemShapeType.Sphere;
shape.radius = 4.0f;
psr.sortMode = ParticleSystemSortMode.YoungestInFront;
// send custom data to the shader
psr.EnableVertexStreams(ParticleSystemVertexStreams.Custom1);
}
void Update() {
Camera mainCam = Camera.main;
ps.GetCustomParticleData(customData, ParticleSystemCustomData.Custom1);
int particleCount = ps.particleCount;
ParticleSystem.Particle[] particles = new ParticleSystem.Particle[particleCount];
ps.GetParticles(particles);
for (int i = 0; i < particles.Length; i++)
{
Vector3 sPos = mainCam.WorldToScreenPoint(particles[i].position + ps.transform.position);
// set custom data to 1, if close enough to the mouse
if (Vector2.Distance(sPos, Input.mousePosition) < minDist)
{
customData[i] = new Vector4(1, 0, 0, 0);
}
// otherwise, fade the custom data back to 0
else
{
float particleLife = particles[i].remainingLifetime / ps.main.startLifetimeMultiplier;
if (customData[i].x > 0)
{
float x = customData[i].x;
x = Mathf.Max(x - Time.deltaTime, 0.0f);
customData[i] = new Vector4(x, 0, 0, 0);
}
}
}
ps.SetCustomParticleData(customData, ParticleSystemCustomData.Custom1);
}
void OnGUI() {
minDist = GUI.HorizontalSlider(new Rect(25, 40, 100, 30), minDist, 0.0f, 100.0f);
}
}
下面是一个自定义着色器示例,可以与上面的脚本配合使用:
Shader "Particles/CustomVertexStream" {
Properties {
_TintColor ("Tint Color", Color) = (0.5,0.5,0.5,0.5)
_MainTex ("Particle Texture", 2D) = "white" {}
_OffsetValue("Offset Value", Range(0,1)) = 0.4
}
Category {
Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" }
Blend SrcAlpha OneMinusSrcAlpha
ColorMask RGB
Cull Off Lighting Off ZWrite Off
SubShader {
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_particles
#pragma multi_compile_fog
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 _TintColor;
float _OffsetValue;
struct appdata_t {
float4 vertex : POSITION;
float3 normal : NORMAL;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 customData : TEXCOORD1;
};
struct v2f {
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float4 customData : TEXCOORD1;
UNITY_FOG_COORDS(2)
};
float4 _MainTex_ST;
v2f vert (appdata_t v)
{
v.vertex.y = lerp(v.vertex.y, v.vertex.y + _OffsetValue, v.customData.x);
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
float4 offsetX = float4(-1, 1, 1, -1);
float4 offsetY = float4(1, 1, -1, -1);
o.color = v.color;
o.texcoord = TRANSFORM_TEX(v.texcoord,_MainTex);
o.customData = v.customData;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = 2.0f * i.color * _TintColor * tex2D(_MainTex, i.texcoord);
fixed4 col2 = fixed4(i.customData.x, i.customData.y, i.customData.z, col.a);
fixed4 final = lerp(col, col*col2, i.customData.x);
UNITY_APPLY_FOG(i.fogCoord, final);
return final;
}
ENDCG
}
}
}
}
下面是一个脚本示例,它在每个粒子诞生时为其分配一个唯一的 ID:
using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
public class ExampleClass : MonoBehaviour {
private ParticleSystem ps;
private List<Vector4> customData = new List<Vector4>();
private int uniqueID;
void Start() {
ps = GetComponent<ParticleSystem>();
}
void Update() {
ps.GetCustomParticleData(customData, ParticleSystemCustomData.Custom1);
for (int i = 0; i < customData.Count; i++)
{
// set custom data to the next ID, if it is in the default 0 state
if (customData[i].x == 0.0f)
{
customData[i] = new Vector4(++uniqueID, 0, 0, 0);
}
}
ps.SetCustomParticleData(customData, ParticleSystemCustomData.Custom1);
}
}