private static void RenderCollisionBounds(ParticleSystem system, GizmoType gizmoType) { if (CollisionModuleUI.s_LastInteractedEditor == null) { return; } if (!CollisionModuleUI.s_LastInteractedEditor.m_VisualizeBounds) { return; } if (CollisionModuleUI.s_LastInteractedEditor.m_ParticleSystemUI.m_ParticleSystem != system) { return; } ParticleSystem.Particle[] array = new ParticleSystem.Particle[system.particleCount]; int particles = system.GetParticles(array); Color color = Gizmos.color; Gizmos.color = Color.green; Matrix4x4 matrix4x = Matrix4x4.identity; if (system.simulationSpace == ParticleSystemSimulationSpace.Local) { matrix4x = system.transform.localToWorldMatrix; } for (int i = 0; i < particles; i++) { ParticleSystem.Particle particle = array[i]; Gizmos.DrawWireSphere(matrix4x.MultiplyPoint(particle.position), particle.GetCurrentSize(system) * 0.5f * CollisionModuleUI.s_LastInteractedEditor.m_RadiusScale.floatValue); } Gizmos.color = color; }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); int numberOfParticles = m_particleSystem.GetParticles(m_particleArray); if (m_particleArray == null || m_particleArray.Length <= 0) { return; } for (int i = 0; i < numberOfParticles; i++) { ParticleSystem.Particle particle = m_particleArray[i]; Vector2[] particleVertices = new[] { Vector2.zero, Vector2.zero, Vector2.zero, Vector2.zero }; float size = particle.GetCurrentSize(m_particleSystem) * m_sizeMultiplier; Vector3 partPosition = particle.position * m_sizeMultiplier; Vector2 partCorner1 = (Vector2)(partPosition) + new Vector2(-(size / 2), -(size / 2)); Vector2 partCorner2 = (Vector2)(partPosition) + new Vector2((size / 2), (size / 2)); particleVertices[0] = new Vector2(partCorner1.x, partCorner1.y); particleVertices[1] = new Vector2(partCorner1.x, partCorner2.y); particleVertices[2] = new Vector2(partCorner2.x, partCorner2.y); particleVertices[3] = new Vector2(partCorner2.x, partCorner1.y); particleVertices[0] = CanvasParticleHelper.RotatePointAroundPivot(particleVertices[0], partPosition, new Vector3(0, 0, -particle.rotation)); particleVertices[1] = CanvasParticleHelper.RotatePointAroundPivot(particleVertices[1], partPosition, new Vector3(0, 0, -particle.rotation)); particleVertices[2] = CanvasParticleHelper.RotatePointAroundPivot(particleVertices[2], partPosition, new Vector3(0, 0, -particle.rotation)); particleVertices[3] = CanvasParticleHelper.RotatePointAroundPivot(particleVertices[3], partPosition, new Vector3(0, 0, -particle.rotation)); Vector2[] particleUV = new Vector2[4]; if (m_AtlasUVs != null && m_AtlasUVs.Count > 1) { int particleFrame = Mathf.FloorToInt((((particle.startLifetime - particle.remainingLifetime)) * m_AtlasUVs.Count) / particle.startLifetime); Vector4 textUV = m_AtlasUVs[particleFrame]; particleUV[0] = new Vector2(textUV.x, textUV.w); particleUV[1] = new Vector2(textUV.x, textUV.y); particleUV[2] = new Vector2(textUV.z, textUV.y); particleUV[3] = new Vector2(textUV.z, textUV.w); } else { particleUV[0] = new Vector2(0, 1); particleUV[1] = Vector2.zero; particleUV[2] = new Vector2(1, 0); particleUV[3] = new Vector2(1, 1); } SetMesh(vh, particleVertices, particleUV, particle.GetCurrentColor(m_particleSystem)); } }
protected override void OnPopulateMesh(VertexHelper vh) { vh.Clear(); if (!base.gameObject.activeInHierarchy) { return; } int particles = _particleSystem.GetParticles(_particles); for (int i = 0; i < particles; i++) { ParticleSystem.Particle particle = _particles[i]; Vector2 vector = ((_particleSystem.simulationSpace != 0) ? _transform.InverseTransformPoint(particle.position) : particle.position); float num = (0f - particle.rotation) * ((float)Math.PI / 180f); float f = num + (float)Math.PI / 2f; Color32 currentColor = particle.GetCurrentColor(_particleSystem); float num2 = particle.GetCurrentSize(_particleSystem) * 0.5f; if (_particleSystem.scalingMode == ParticleSystemScalingMode.Shape) { vector /= base.canvas.scaleFactor; } Vector4 uv = _uv; if (_textureSheetAnimation.enabled) { float num3 = 1f - particle.remainingLifetime / particle.startLifetime; num3 = Mathf.Repeat(num3 * (float)_textureSheetAnimation.cycleCount, 1f); int num4 = 0; switch (_textureSheetAnimation.animation) { case ParticleSystemAnimationType.WholeSheet: num4 = Mathf.FloorToInt(num3 * (float)_textureSheetAnimationFrames); break; case ParticleSystemAnimationType.SingleRow: { num4 = Mathf.FloorToInt(num3 * (float)_textureSheetAnimation.numTilesX); int rowIndex = _textureSheetAnimation.rowIndex; num4 += rowIndex * _textureSheetAnimation.numTilesX; break; } } num4 %= _textureSheetAnimationFrames; uv.x = (float)(num4 % _textureSheetAnimation.numTilesX) * _textureSheedAnimationFrameSize.x; uv.y = (float)Mathf.FloorToInt(num4 / _textureSheetAnimation.numTilesX) * _textureSheedAnimationFrameSize.y; uv.z = uv.x + _textureSheedAnimationFrameSize.x; uv.w = uv.y + _textureSheedAnimationFrameSize.y; } ref UIVertex reference = ref _quad[0]; reference = UIVertex.simpleVert; _quad[0].color = currentColor; _quad[0].uv0 = new Vector2(uv.x, uv.y); ref UIVertex reference2 = ref _quad[1];
// ... void LateUpdate() { ParticleSystem.Particle[] particles = new ParticleSystem.Particle[ps.particleCount]; int numOfParticles = ps.GetParticles(particles); if (lights.Count != numOfParticles) { for (int i = 0; i < lights.Count; i++) { Destroy(lights[i].gameObject); } lights.Clear(); for (int i = 0; i < numOfParticles; i++) { GameObject go = Instantiate(template, transform) as GameObject; go.name = "- " + (i + 1).ToString(); lights.Add(go.AddComponent <Light>()); } } ParticleSystem.MainModule m = ps.main; bool worldSpace = m.simulationSpace == ParticleSystemSimulationSpace.World; for (int i = 0; i < numOfParticles; i++) { ParticleSystem.Particle p = particles[i]; Light light = lights[i]; //light.type = type; //if (type == LightType.Spot) //{ // light.transform.rotation = Quaternion.Euler(p.rotation3D); //} light.range = p.GetCurrentSize(ps) * scale; light.color = Color.Lerp(colour, p.GetCurrentColor(ps), colourFromParticle); light.intensity = intensity; light.shadows = shadows; light.transform.position = worldSpace ? p.position : ps.transform.TransformPoint(p.position); } }
private static void RenderCollisionBounds(ParticleSystem system, GizmoType gizmoType) { if (((s_LastInteractedEditor != null) && s_LastInteractedEditor.m_VisualizeBounds) && (s_LastInteractedEditor.m_ParticleSystemUI.m_ParticleSystem == system)) { ParticleSystem.Particle[] particles = new ParticleSystem.Particle[system.particleCount]; int num = system.GetParticles(particles); Color color = Gizmos.color; Gizmos.color = Color.green; Matrix4x4 identity = Matrix4x4.identity; if (system.simulationSpace == ParticleSystemSimulationSpace.Local) { identity = system.transform.localToWorldMatrix; } for (int i = 0; i < num; i++) { ParticleSystem.Particle particle = particles[i]; Vector3 center = identity.MultiplyPoint(particle.position); Gizmos.DrawWireSphere(center, (particle.GetCurrentSize(system) * 0.5f) * s_LastInteractedEditor.m_RadiusScale.floatValue); } Gizmos.color = color; } }
void Update() { GetParticleSystem(); int particlesAlive = particleSystem2D.GetParticles(particleArray); for (int p = 0; p < particlesAlive; p++) { ParticleSystem.Particle particle = particleArray [p]; if (particle.remainingLifetime < 0.01f || particle.GetCurrentSize(particleSystem2D) < 0.01f) { continue; } particle.startSize *= (1f - 5f * Time.deltaTime); particleArray[p] = particle; } particleSystem2D.SetParticles(particleArray, particlesAlive); }
void LateUpdate() { if (Detector == null || _meshMode == MeshMode.Unsupported) { return; } switch (_meshMode) { case MeshMode.MeshRendered: { Matrix4x4 localToWorldMatrix = transform.localToWorldMatrix; UpdateMesh(localToWorldMatrix); } break; case MeshMode.ParticleRendered: { int numParticlesAlive = _particleSystem.GetParticles(_particles); if (numParticlesAlive > 0) //只适用于单个粒子 { ParticleSystem.Particle particle = _particles[0]; Matrix4x4 localToWorldMatrix = transform.localToWorldMatrix; Vector3 particlePos = _particleSystem.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : Vector3.zero; Quaternion particleRot = Quaternion.Euler(particle.rotation3D); float scale = particle.GetCurrentSize(_particleSystem); if (scale == 0) { scale = 0.0001f; } Vector3 particleScale = new Vector3(scale, scale, scale); Matrix4x4 matLocal = Matrix4x4.TRS(particlePos, particleRot, particleScale); localToWorldMatrix *= matLocal; UpdateMesh(localToWorldMatrix); } } break; } }
private void LateUpdate() { Init(); // GetParticles is allocation free because we reuse the m_Particles buffer between updates int numParticlesAlive = m_CachedParticleSystem.GetParticles(m_ParticleSpawners); // Change only the particles that are alive for (int i = 0; i < numParticlesAlive; i++) { ParticleSystem.Particle p = m_ParticleSpawners[i]; if (Vector3.Distance(p.position, m_PrevPosition[i]) > m_DistanceBetweenParticles) { m_EmitParams.startSize = p.GetCurrentSize(m_CachedParticleSystem); m_EmitParams.position = p.position + Random.insideUnitSphere * m_PosDeviation; m_PlumeParticles.Emit(m_EmitParams, 1); } m_PrevPosition[i] = p.position; } // Apply the particle changes to the particle system m_CachedParticleSystem.SetParticles(m_ParticleSpawners, numParticlesAlive); }
private static void RenderCollisionBounds(ParticleSystem system, GizmoType gizmoType) { if (CollisionModuleUI.s_LastInteractedEditor == null || !CollisionModuleUI.s_LastInteractedEditor.m_VisualizeBounds || (Object)CollisionModuleUI.s_LastInteractedEditor.m_ParticleSystemUI.m_ParticleSystem != (Object)system) { return; } ParticleSystem.Particle[] particles1 = new ParticleSystem.Particle[system.particleCount]; int particles2 = system.GetParticles(particles1); Color color = Gizmos.color; Gizmos.color = Color.green; Matrix4x4 matrix4x4 = Matrix4x4.identity; if (system.simulationSpace == ParticleSystemSimulationSpace.Local) { matrix4x4 = system.transform.localToWorldMatrix; } for (int index = 0; index < particles2; ++index) { ParticleSystem.Particle particle = particles1[index]; Gizmos.DrawWireSphere(matrix4x4.MultiplyPoint(particle.position), particle.GetCurrentSize(system) * 0.5f * CollisionModuleUI.s_LastInteractedEditor.m_RadiusScale.floatValue); } Gizmos.color = color; }
void UpdateGeometry() { #if UNITY_EDITOR if (mUpdateFrame != Time.frameCount || !Application.isPlaying) #else if (mUpdateFrame != Time.frameCount) #endif { mUpdateFrame = Time.frameCount; if (GetComponent <ParticleSystem>() != null) { // int max_particles = GetComponent <ParticleSystem>().maxParticles; m_Particles.Adjust(max_particles); bool isBufferChanged = m_Meshes.Adjust(max_particles, true); ParticleSystem.Particle[] particles = m_Particles.GetBuffer(); GetComponent <ParticleSystem>().GetParticles(particles); // ParticleMesh[] meshes = m_Meshes.GetBuffer(); int mesh_count = meshes.Length; int particle_count = GetComponent <ParticleSystem>().particleCount; if (isBufferChanged) { UnityEngine.Profiling.Profiler.BeginSample("FXBillboardParticle 001"); for (int i = particle_count; i < mesh_count; i++) { if (meshes[i].m_Renderer != null) { meshes[i].m_Renderer.enabled = false; } } UnityEngine.Profiling.Profiler.EndSample(); } UnityEngine.Profiling.Profiler.BeginSample("FXBillboardParticle 002"); for (int i = 0; i < particle_count; i++) { ParticleSystem.Particle particle = particles[i]; float factor = (particle.startLifetime - particle.remainingLifetime) / particle.startLifetime; float size = particle.GetCurrentSize(GetComponent <ParticleSystem>()) * Mathf.Lerp(FromSize, ToSize, factor); Matrix4x4 transform_matrix = Matrix4x4.TRS(particle.position, Quaternion.AngleAxis(particle.rotation, -Camera.main.transform.forward), new Vector3(size, size, size)); meshes[i].PreUpdate(transform); if (AtlasType == FXAtlasType.Static) { if (meshes[i].m_Renderer != null && m_Atlas != null) { meshes[i].m_Renderer.sharedMaterial = m_Atlas.spriteMaterial; meshes[i].m_Renderer.enabled = true; } } else if (AtlasType == FXAtlasType.Dynamic) { DynamicAtlasManager dynamic_atlas_manager = DynamicAtlasManager.GetInstance(); if (meshes[i].m_Renderer != null && dynamic_atlas_manager != null) { DynamicAtlas dynamic_atlas = dynamic_atlas_manager.GetDynamicAtlas(m_DynamicAtlasType); if (dynamic_atlas != null) { meshes[i].m_Renderer.sharedMaterial = dynamic_atlas.m_Material; meshes[i].m_Renderer.enabled = true; } } } if (GetComponent <ParticleSystem>().simulationSpace == ParticleSystemSimulationSpace.Local) { meshes[i].m_Vertices[0].Set(-0.5f, -0.5f, 0); meshes[i].m_Vertices[0] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[0]); meshes[i].m_Vertices[1].Set(-0.5f, 0.5f, 0); meshes[i].m_Vertices[1] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[1]); meshes[i].m_Vertices[2].Set(0.5f, 0.5f, 0); meshes[i].m_Vertices[2] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[2]); meshes[i].m_Vertices[3].Set(0.5f, -0.5f, 0); meshes[i].m_Vertices[3] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[3]); } else { Matrix4x4 world2local_matrix = transform.worldToLocalMatrix; meshes[i].m_Vertices[0].Set(-0.5f, -0.5f, 0); meshes[i].m_Vertices[0] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[0]); meshes[i].m_Vertices[0] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[0]); meshes[i].m_Vertices[1].Set(-0.5f, 0.5f, 0); meshes[i].m_Vertices[1] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[1]); meshes[i].m_Vertices[1] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[1]); meshes[i].m_Vertices[2].Set(0.5f, 0.5f, 0); meshes[i].m_Vertices[2] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[2]); meshes[i].m_Vertices[2] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[2]); meshes[i].m_Vertices[3].Set(0.5f, -0.5f, 0); meshes[i].m_Vertices[3] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[3]); meshes[i].m_Vertices[3] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[3]); } // Rect uv = m_SpriteUV; float frame = TileX * TileY * factor; int frame_index = (int)frame; int frameX = frame_index % TileX; int frameY = TileY - frame_index / TileY - 1; float stepX = m_SpriteUV.width / (float)TileX; float stepY = m_SpriteUV.height / (float)TileY; uv.Set(stepX * frameX + m_SpriteUV.x, stepY * frameY + m_SpriteUV.y, stepX, stepY); meshes[i].m_UVs[0].Set(uv.xMin, uv.yMin); meshes[i].m_UVs[1].Set(uv.xMin, uv.yMax); meshes[i].m_UVs[2].Set(uv.xMax, uv.yMax); meshes[i].m_UVs[3].Set(uv.xMax, uv.yMin); // Color color = particle.GetCurrentColor(GetComponent <ParticleSystem>()) * Color.Lerp(FromColor, ToColor, factor); meshes[i].m_Colors[0] = color; meshes[i].m_Colors[1] = color; meshes[i].m_Colors[2] = color; meshes[i].m_Colors[3] = color; meshes[i].m_Indices[0] = 0; meshes[i].m_Indices[1] = 1; meshes[i].m_Indices[2] = 2; meshes[i].m_Indices[3] = 0; meshes[i].m_Indices[4] = 2; meshes[i].m_Indices[5] = 3; meshes[i].Update(); } UnityEngine.Profiling.Profiler.EndSample(); } } }
protected override void OnPopulateMesh(VertexHelper vh) { #if UNITY_EDITOR if (!Application.isPlaying) { if (!Initialize()) { return; } } #endif // prepare vertices vh.Clear(); if (!gameObject.activeInHierarchy) { return; } // iterate through current particles int count = _particleSystem.GetParticles(_particles); for (int i = 0; i < count; ++i) { ParticleSystem.Particle particle = _particles[i]; // get particle properties Vector2 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 scale if (_particleSystem.scalingMode == ParticleSystemScalingMode.Shape) { position /= canvas.scaleFactor; } // apply texture sheet animation Vector4 particleUV = _uv; if (_textureSheetAnimation.enabled) { float frameProgress = 1 - (particle.remainingLifetime / particle.startLifetime); // float frameProgress = textureSheetAnimation.frameOverTime.curveMin.Evaluate(1 - (particle.lifetime / particle.startLifetime)); // TODO - once Unity allows MinMaxCurve reading frameProgress = 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 rotation Vector2 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 rotation Vector2 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); } }
protected override void OnPopulateMesh(VertexHelper vh) { #if UNITY_EDITOR if (!Application.isPlaying) { if (!Initialize()) { return; } } #endif // prepare vertices vh.Clear(); if (!gameObject.activeInHierarchy) { return; } if (!isInitialised && !pSystem.main.playOnAwake) { pSystem.Stop(false, ParticleSystemStopBehavior.StopEmittingAndClear); isInitialised = true; } Vector2 temp = Vector2.zero; Vector2 corner1 = Vector2.zero; Vector2 corner2 = Vector2.zero; // iterate through current particles int count = pSystem.GetParticles(particles); for (int i = 0; i < count; ++i) { ParticleSystem.Particle particle = particles[i]; // get particle properties #if UNITY_5_5_OR_NEWER Vector2 position = (mainModule.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position)); #else Vector2 position = (pSystem.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position)); #endif float rotation = -particle.rotation * Mathf.Deg2Rad; float rotation90 = rotation + Mathf.PI / 2; Color32 color = particle.GetCurrentColor(pSystem); float size = particle.GetCurrentSize(pSystem) * 0.5f; // apply scale #if UNITY_5_5_OR_NEWER if (mainModule.scalingMode == ParticleSystemScalingMode.Shape) { position /= canvas.scaleFactor; } #else if (pSystem.scalingMode == ParticleSystemScalingMode.Shape) { position /= canvas.scaleFactor; } #endif // apply texture sheet animation Vector4 particleUV = imageUV; if (textureSheetAnimation.enabled) { #if UNITY_5_5_OR_NEWER float frameProgress = 1 - (particle.remainingLifetime / particle.startLifetime); if (textureSheetAnimation.frameOverTime.curveMin != null) { frameProgress = textureSheetAnimation.frameOverTime.curveMin.Evaluate(1 - (particle.remainingLifetime / particle.startLifetime)); } else if (textureSheetAnimation.frameOverTime.curve != null) { frameProgress = textureSheetAnimation.frameOverTime.curve.Evaluate(1 - (particle.remainingLifetime / particle.startLifetime)); } else if (textureSheetAnimation.frameOverTime.constant > 0) { frameProgress = textureSheetAnimation.frameOverTime.constant - (particle.remainingLifetime / particle.startLifetime); } #else float frameProgress = 1 - (particle.lifetime / particle.startLifetime); #endif frameProgress = 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) * textureSheetAnimationFrameSize.x; particleUV.y = 1.0f - Mathf.FloorToInt(frame / textureSheetAnimation.numTilesX) * textureSheetAnimationFrameSize.y; particleUV.z = particleUV.x + textureSheetAnimationFrameSize.x; particleUV.w = particleUV.y + textureSheetAnimationFrameSize.y; } temp.x = particleUV.x; temp.y = particleUV.y; _quad[0] = UIVertex.simpleVert; _quad[0].color = color; _quad[0].uv0 = temp; temp.x = particleUV.x; temp.y = particleUV.w; _quad[1] = UIVertex.simpleVert; _quad[1].color = color; _quad[1].uv0 = temp; temp.x = particleUV.z; temp.y = particleUV.w; _quad[2] = UIVertex.simpleVert; _quad[2].color = color; _quad[2].uv0 = temp; temp.x = particleUV.z; temp.y = particleUV.y; _quad[3] = UIVertex.simpleVert; _quad[3].color = color; _quad[3].uv0 = temp; if (rotation == 0) { // no rotation corner1.x = position.x - size; corner1.y = position.y - size; corner2.x = position.x + size; corner2.y = position.y + size; temp.x = corner1.x; temp.y = corner1.y; _quad[0].position = temp; temp.x = corner1.x; temp.y = corner2.y; _quad[1].position = temp; temp.x = corner2.x; temp.y = corner2.y; _quad[2].position = temp; temp.x = corner2.x; temp.y = corner1.y; _quad[3].position = temp; } else { if (use3dRotation) { // get particle properties #if UNITY_5_5_OR_NEWER Vector3 pos3d = (mainModule.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position)); #else Vector3 pos3d = (pSystem.simulationSpace == ParticleSystemSimulationSpace.Local ? particle.position : _transform.InverseTransformPoint(particle.position)); #endif // apply scale #if UNITY_5_5_OR_NEWER if (mainModule.scalingMode == ParticleSystemScalingMode.Shape) { position /= canvas.scaleFactor; } #else if (pSystem.scalingMode == ParticleSystemScalingMode.Shape) { position /= canvas.scaleFactor; } #endif Vector3[] verts = new Vector3[4] { new Vector3(-size, -size, 0), new Vector3(-size, size, 0), new Vector3(size, size, 0), new Vector3(size, -size, 0) }; Quaternion particleRotation = Quaternion.Euler(particle.rotation3D); _quad[0].position = pos3d + particleRotation * verts[0]; _quad[1].position = pos3d + particleRotation * verts[1]; _quad[2].position = pos3d + particleRotation * verts[2]; _quad[3].position = pos3d + particleRotation * verts[3]; } else { // apply rotation Vector2 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); } }
protected override void OnPopulateMesh(VertexHelper vh) { #if UNITY_EDITOR if (!Application.isPlaying) { if (!Initialize()) { return; } } #endif // prepare vertices vh.Clear(); if (!gameObject.activeInHierarchy) { return; } Vector2 temp = Vector2.zero; Vector2 corner1 = Vector2.zero; Vector2 corner2 = Vector2.zero; // iterate through current particles int count = pSystem.GetParticles(particles); for (int i = 0; i < count; ++i) { ParticleSystem.Particle particle = particles[i]; // get particle properties Vector2 position = (mainModule.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(pSystem); float size = particle.GetCurrentSize(pSystem) * 0.5f; // apply scale if (mainModule.scalingMode == ParticleSystemScalingMode.Shape) { position /= canvas.scaleFactor; } // apply texture sheet animation Vector4 particleUV = imageUV; if (textureSheetAnimation.enabled) { float frameProgress = 1 - (particle.remainingLifetime / particle.startLifetime); if (textureSheetAnimation.frameOverTime.curveMin != null) { frameProgress = textureSheetAnimation.frameOverTime.curveMin.Evaluate(1 - (particle.remainingLifetime / particle.startLifetime)); } else if (textureSheetAnimation.frameOverTime.curve != null) { frameProgress = textureSheetAnimation.frameOverTime.curve.Evaluate(1 - (particle.remainingLifetime / particle.startLifetime)); } else if (textureSheetAnimation.frameOverTime.constant > 0) { frameProgress = textureSheetAnimation.frameOverTime.constant - (particle.remainingLifetime / particle.startLifetime); } frameProgress = 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; frame += row * textureSheetAnimation.numTilesX; break; } frame %= textureSheetAnimationFrames; particleUV.x = (frame % textureSheetAnimation.numTilesX) * textureSheetAnimationFrameSize.x; particleUV.y = Mathf.FloorToInt(frame / textureSheetAnimation.numTilesX) * textureSheetAnimationFrameSize.y; particleUV.z = particleUV.x + textureSheetAnimationFrameSize.x; particleUV.w = particleUV.y + textureSheetAnimationFrameSize.y; } temp.x = particleUV.x; temp.y = particleUV.y; _quad[0] = UIVertex.simpleVert; _quad[0].color = color; _quad[0].uv0 = temp; temp.x = particleUV.x; temp.y = particleUV.w; _quad[1] = UIVertex.simpleVert; _quad[1].color = color; _quad[1].uv0 = temp; temp.x = particleUV.z; temp.y = particleUV.w; _quad[2] = UIVertex.simpleVert; _quad[2].color = color; _quad[2].uv0 = temp; temp.x = particleUV.z; temp.y = particleUV.y; _quad[3] = UIVertex.simpleVert; _quad[3].color = color; _quad[3].uv0 = temp; if (rotation == 0) { // no rotation corner1.x = position.x - size; corner1.y = position.y - size; corner2.x = position.x + size; corner2.y = position.y + size; temp.x = corner1.x; temp.y = corner1.y; _quad[0].position = temp; temp.x = corner1.x; temp.y = corner2.y; _quad[1].position = temp; temp.x = corner2.x; temp.y = corner2.y; _quad[2].position = temp; temp.x = corner2.x; temp.y = corner1.y; _quad[3].position = temp; } else { // apply rotation Vector2 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); } }
public void ReconstructParticleSystem() { foreach (ParticleCollider curParticleCollider in particleColliders) { GameObject curGO = curParticleCollider.gameObject; ParticleSystem.Particle curParticle = curParticleCollider.Particle; float rotationCorrection = 1f; Vector3 pivot = particleSystemRenderer.pivot; Vector3 size = curParticle.GetCurrentSize3D(particleSys); // Get hierarchy scale Vector3 transformScale = particleSys.transform.localScale; // Apply position switch (particleSys.main.simulationSpace) { case ParticleSystemSimulationSpace.Local: curGO.transform.SetParent(particleSys.gameObject.transform); curGO.transform.localPosition = curParticle.position; pivot = Vector3.Scale(pivot, transformScale); break; case ParticleSystemSimulationSpace.World: curGO.transform.SetParent(null); curGO.transform.position = curParticle.position; size = Vector3.Scale(size, transformScale); break; } switch (particleSystemRenderer.renderMode) { case ParticleSystemRenderMode.Billboard: // Billboard to camera curGO.transform.LookAt(curGO.transform.position + cam.transform.rotation * Vector3.forward, cam.transform.rotation * Vector3.up); rotationCorrection = -1f; break; case ParticleSystemRenderMode.Mesh: curGO.transform.rotation = Quaternion.identity; // For mesh pivots, Z is Y and Y is Z pivot.z = particleSystemRenderer.pivot.y * -1f; pivot.y = particleSystemRenderer.pivot.z * -1f; pivot *= curParticle.GetCurrentSize(particleSys); break; default: Debug.LogError("Unsupported render mode " + particleSystemRenderer.renderMode); break; } // Apply rotation curGO.transform.Rotate(new Vector3(curParticle.rotation3D.x, curParticle.rotation3D.y, curParticle.rotation3D.z * rotationCorrection)); // Apply scale curGO.transform.localScale = size; // Apply pivot pivot = Vector3.Scale(pivot, size); curGO.transform.position += (curGO.transform.right * pivot.x); curGO.transform.position += (curGO.transform.up * pivot.y); curGO.transform.position += (curGO.transform.forward * pivot.z * -1f); // Apply texture sheet animation ParticleSystem.TextureSheetAnimationModule texModule = particleSys.textureSheetAnimation; if (texModule.enabled) { SubUVTextureInfo subUV = new SubUVTextureInfo(texModule, curParticle); switch (texModule.animation) { case ParticleSystemAnimationType.WholeSheet: curParticleCollider.gameObject.GetComponent <MeshRenderer>().material.mainTextureScale = new Vector2(1 / subUV.columns, 1 / subUV.rows); curParticleCollider.gameObject.GetComponent <MeshRenderer>().material.mainTextureOffset = new Vector2(subUV.currentColumn / subUV.columns, (subUV.rows - subUV.currentRow - 1) / subUV.rows); break; case ParticleSystemAnimationType.SingleRow: Debug.Log("Single Row texture sheet animations currently not supported."); break; default: Debug.Log("Unsupported texture sheet animation animation type."); break; } } // Apply color Color particleColor = curParticle.GetCurrentColor(particleSys); Material mat = curGO.GetComponent <MeshRenderer>().material; Color matColor = particleSystemRenderer.material.GetColor(TINT_COLOR); curGO.GetComponent <MeshRenderer>().material.SetColor(TINT_COLOR, particleColor * matColor); } }
private void LateUpdate() { if (m_UseMesh) { m_Verticies.Clear(); m_Triangles.Clear(); m_VertexColors.Clear(); } CreateOrUpdateArrays(); m_PS.GetParticles(m_Particles); m_ParticleCount = m_PS.particleCount; m_VertexIndex = 0; m_LineIndex = 0; if (m_UseMesh) { for (int i = 0; i < m_ParticleCount; ++i) { m_ParticleMeshData[i].ClearData(); } } switch (m_ParticleMainModule.simulationSpace) { case ParticleSystemSimulationSpace.Local: { m_SimulationTransform = transform; break; } case ParticleSystemSimulationSpace.World: { m_SimulationTransform = transform; m_SimulationTransformMatrix = transform.worldToLocalMatrix; break; } case ParticleSystemSimulationSpace.Custom: { m_SimulationTransform = m_ParticleMainModule.customSimulationSpace; m_SimulationTransformMatrix = m_SimulationTransform.localToWorldMatrix * transform.worldToLocalMatrix; break; } } for (int i = 0; i < m_ParticleCount; ++i) { ParticleSystem.Particle firstParticle = m_Particles[i]; int currentLinesCount = 0; if (m_LineIndex >= m_MaxLinesCount) { break; } for (int j = i + 1; j < m_ParticleCount; ++j) { if (currentLinesCount >= m_MaxLinesPerParticle || m_LineIndex >= m_MaxLinesCount) { break; } ParticleSystem.Particle secondParticle = m_Particles[j]; float particleSqrDst = (firstParticle.position - secondParticle.position).sqrMagnitude; if (particleSqrDst < m_SearchDst * m_SearchDst) { LineRenderer line = GetNextLine(); line.useWorldSpace = m_ParticleMainModule.simulationSpace == ParticleSystemSimulationSpace.World; line.SetPosition(0, firstParticle.position); line.SetPosition(1, secondParticle.position); //Set line Width line.startWidth = Mathf.Lerp(m_LineWidths[0], firstParticle.GetCurrentSize(m_PS), m_LineSizeFromParticle); line.endWidth = Mathf.Lerp(m_LineWidths[1], secondParticle.GetCurrentSize(m_PS), m_LineSizeFromParticle); //Set Line Color line.startColor = Color.Lerp(m_LineColors[0], firstParticle.GetCurrentColor(m_PS), m_LineColorFromParticle); line.endColor = Color.Lerp(m_LineColors[1], secondParticle.GetCurrentColor(m_PS), m_LineColorFromParticle); ++m_LineIndex; ++currentLinesCount; if (m_UseMesh) { m_ParticleMeshData[i].AddNeighbor(j); } } } } //Hide unused lines for (int i = m_LineIndex; i < m_LinePool.Count; ++i) { m_LinePool[i].gameObject.SetActive(false); } if (m_UseMesh) { SetUpMesh(); } else { m_Mesh.Clear(); } }
private void DrawParticleBillboard(ParticleSystem.Particle particle, VertexHelper vh) { var center = particle.position; var rotation = Quaternion.Euler(particle.rotation3D); if (ParticleSystem.main.simulationSpace == ParticleSystemSimulationSpace.World) { center = rectTransform.InverseTransformPoint(center); } float timeAlive = particle.startLifetime - particle.remainingLifetime; float globalTimeAlive = timeAlive / particle.startLifetime; Vector3 size3D = Vector3.zero; #if UNITY_5_4_OR_NEWER size3D = particle.GetCurrentSize3D(ParticleSystem); #else var size = particle.GetCurrentSize(ParticleSystem); size3D = new Vector3(size, size, size); #endif if (m_RenderMode == UiParticleRenderMode.StreachedBillboard) { GetStrechedBillboardsSizeAndRotation(particle, globalTimeAlive, ref size3D, ref rotation); } var leftTop = new Vector3(-size3D.x * 0.5f, size3D.y * 0.5f); var rightTop = new Vector3(size3D.x * 0.5f, size3D.y * 0.5f); var rightBottom = new Vector3(size3D.x * 0.5f, -size3D.y * 0.5f); var leftBottom = new Vector3(-size3D.x * 0.5f, -size3D.y * 0.5f); leftTop = rotation * leftTop + center; rightTop = rotation * rightTop + center; rightBottom = rotation * rightBottom + center; leftBottom = rotation * leftBottom + center; Color32 color32 = particle.GetCurrentColor(ParticleSystem); var i = vh.currentVertCount; Vector2[] uvs = new Vector2[4]; if (!ParticleSystem.textureSheetAnimation.enabled) { uvs [0] = new Vector2(0f, 0f); uvs [1] = new Vector2(0f, 1f); uvs [2] = new Vector2(1f, 1f); uvs [3] = new Vector2(1f, 0f); } else { var textureAnimator = ParticleSystem.textureSheetAnimation; float lifeTimePerCycle = particle.startLifetime / textureAnimator.cycleCount; float timePerCycle = timeAlive % lifeTimePerCycle; float timeAliveAnim01 = timePerCycle / lifeTimePerCycle;; // in percents float frame01; var totalFramesCount = textureAnimator.numTilesY * textureAnimator.numTilesX; #if UNITY_5_4_OR_NEWER frame01 = textureAnimator.frameOverTime.Evaluate(timeAliveAnim01); #else frame01 = m_FrameOverLifetime.Evaluate(timeAliveAnim01, (int)particle.randomSeed, 0, totalFramesCount - 1); #endif var frame = 0f; switch (textureAnimator.animation) { case ParticleSystemAnimationType.WholeSheet: { frame = Mathf.Clamp(Mathf.Floor(frame01 * totalFramesCount), 0, totalFramesCount - 1); break; } case ParticleSystemAnimationType.SingleRow: { frame = Mathf.Clamp(Mathf.Floor(frame01 * textureAnimator.numTilesX), 0, textureAnimator.numTilesX - 1); int row = textureAnimator.rowIndex; if (textureAnimator.useRandomRow) { Random.InitState((int)particle.randomSeed); row = Random.Range(0, textureAnimator.numTilesY); } frame += row * textureAnimator.numTilesX; break; } } int x = (int)frame % textureAnimator.numTilesX; int y = (int)frame / textureAnimator.numTilesY; var xDelta = 1f / textureAnimator.numTilesX; var yDelta = 1f / textureAnimator.numTilesY; y = textureAnimator.numTilesY - 1 - y; var sX = x * xDelta; var sY = y * yDelta; var eX = sX + xDelta; var eY = sY + yDelta; uvs [0] = new Vector2(sX, sY); uvs [1] = new Vector2(sX, eY); uvs [2] = new Vector2(eX, eY); uvs [3] = new Vector2(eX, sY); } vh.AddVert(leftBottom, color32, uvs [0]); vh.AddVert(leftTop, color32, uvs [1]); vh.AddVert(rightTop, color32, uvs [2]); vh.AddVert(rightBottom, color32, uvs [3]); vh.AddTriangle(i, i + 1, i + 2); vh.AddTriangle(i + 2, i + 3, i); }
/// <summary> /// Handles the particle update /// </summary> /// <param name="particle">Current assigned particle</param> protected override void HandleParticleUpdate(ParticleSystem.Particle particle, ParticleSystem particleSystem) { this.lightSource.intensity = this.intensitySizeRelation * particle.GetCurrentSize(particleSystem); this.lightSource.color = particle.GetCurrentColor(particleSystem); }