/// <summary> /// Checks the trail. /// </summary> void CheckTrail() { if (isActiveAndEnabled && !m_IsTrail && m_ParticleSystem && m_ParticleSystem.trails.enabled) { if (!m_TrailParticle) { m_TrailParticle = new GameObject("[UIParticle] Trail").AddComponent <UIParticle> (); var trans = m_TrailParticle.transform; trans.SetParent(transform); trans.localPosition = Vector3.zero; trans.localRotation = Quaternion.identity; trans.localScale = Vector3.one; trans.gameObject.layer = gameObject.layer; m_TrailParticle._renderer = GetComponent <ParticleSystemRenderer> (); m_TrailParticle.m_ParticleSystem = GetComponent <ParticleSystem> (); m_TrailParticle.m_IsTrail = true; } m_TrailParticle.enabled = true; } else if (m_TrailParticle) { m_TrailParticle.enabled = false; } }
private static void Refresh(UIParticle particle) { if (!particle || !particle.canvas || !particle.canvasRenderer) { return; } Profiler.BeginSample("[UIParticle] Modify scale"); ModifyScale(particle); Profiler.EndSample(); Profiler.BeginSample("[UIParticle] Bake mesh"); BakeMesh(particle); Profiler.EndSample(); if (QualitySettings.activeColorSpace == ColorSpace.Linear) { Profiler.BeginSample("[UIParticle] Modify color space to linear"); particle.bakedMesh.ModifyColorSpaceToLinear(); Profiler.EndSample(); } Profiler.BeginSample("[UIParticle] Set mesh to CanvasRenderer"); particle.canvasRenderer.SetMesh(particle.bakedMesh); Profiler.EndSample(); Profiler.BeginSample("[UIParticle] Update Animatable Material Properties"); particle.UpdateMaterialProperties(); Profiler.EndSample(); }
void DestroyUIParticle(UIParticle p, bool ignoreCurrent = false) { if (!p || ignoreCurrent && target == p) { return; } var cr = p.canvasRenderer; DestroyImmediate(p); DestroyImmediate(cr); #if UNITY_2018_3_OR_NEWER var stage = UnityEditor.Experimental.SceneManagement.PrefabStageUtility.GetCurrentPrefabStage(); if (stage != null && stage.scene.isLoaded) { #if UNITY_2020_1_OR_NEWER string prefabAssetPath = stage.assetPath; #else string prefabAssetPath = stage.prefabAssetPath; #endif PrefabUtility.SaveAsPrefabAsset(stage.prefabContentsRoot, prefabAssetPath); } #endif }
public static void Unregister(UIParticle particle) { if (!particle) { return; } s_ActiveParticles.Remove(particle); }
public static void Register(UIParticle particle) { if (!particle) { return; } s_ActiveParticles.Add(particle); }
/// <summary> /// This function is called when the parent property of the transform of the GameObject has changed. /// </summary> protected override void OnTransformParentChanged() { UIParticle newParent = null; if (isActiveAndEnabled && !m_IgnoreParent) { var parentTransform = transform.parent; while (parentTransform && (!newParent || !newParent.enabled)) { newParent = parentTransform.GetComponent <UIParticle> (); parentTransform = parentTransform.parent; } } SetParent(newParent); }
/// <summary> /// Set the parent of the soft mask. /// </summary> /// <param name="newParent">The parent soft mask to use.</param> void SetParent(UIParticle newParent) { if (_parent != newParent && this != newParent) { if (_parent && _parent._children.Contains(this)) { _parent._children.Remove(this); _parent._children.RemoveAll(x => x == null); } _parent = newParent; } if (_parent && !_parent._children.Contains(this)) { _parent._children.Add(this); } }
/// <summary> /// Update meshes. /// </summary> static void UpdateMeshes() { for (int i = 0; i < s_ActiveParticles.Count; i++) { if (s_ActiveParticles [i]) { UIParticle up = s_ActiveParticles[i]; if (up != null) { if (up.gameObject.layer == 16 || up.gameObject.layer == 5) { up.UpdateMesh(); } else { up.RevertMesh(); } } } } }
private static void ModifyScale(UIParticle particle) { if (!particle.ignoreCanvasScaler || !particle.canvas) { return; } // Ignore Canvas scaling. var s = particle.canvas.rootCanvas.transform.localScale; var modifiedScale = new Vector3( Mathf.Approximately(s.x, 0) ? 1 : 1 / s.x, Mathf.Approximately(s.y, 0) ? 1 : 1 / s.y, Mathf.Approximately(s.z, 0) ? 1 : 1 / s.z); // Scale is already modified. var transform = particle.transform; if (Mathf.Approximately((transform.localScale - modifiedScale).sqrMagnitude, 0)) { return; } transform.localScale = modifiedScale; }
private static void BakeMesh(UIParticle particle) { // Clear mesh before bake. MeshHelper.Clear(); particle.bakedMesh.Clear(false); // Get camera for baking mesh. var camera = BakingCamera.GetCamera(particle.canvas); var root = particle.transform; var rootMatrix = Matrix4x4.Rotate(root.rotation).inverse *Matrix4x4.Scale(root.lossyScale).inverse; var scale = particle.ignoreCanvasScaler ? Vector3.Scale(particle.canvas.rootCanvas.transform.localScale, particle.scale3D) : particle.scale3D; var scaleMatrix = Matrix4x4.Scale(scale); // Cache position var position = particle.transform.position; var diff = position - particle.cachedPosition; diff.x *= 1f - 1f / Mathf.Max(0.001f, scale.x); diff.y *= 1f - 1f / Mathf.Max(0.001f, scale.y); diff.z *= 1f - 1f / Mathf.Max(0.001f, scale.z); particle.cachedPosition = position; for (var i = 0; i < particle.particles.Count; i++) { // No particle to render. var currentPs = particle.particles[i]; if (!currentPs || !currentPs.IsAlive() || currentPs.particleCount == 0) { continue; } // Calc matrix. var matrix = rootMatrix; if (currentPs.transform != root) { if (currentPs.main.simulationSpace == ParticleSystemSimulationSpace.Local) { var relativePos = root.InverseTransformPoint(currentPs.transform.position); matrix = Matrix4x4.Translate(relativePos) * matrix; } else { matrix = matrix * Matrix4x4.Translate(-root.position); } } else { matrix = GetScaledMatrix(currentPs); } matrix = scaleMatrix * matrix; // Extra world simulation. if (currentPs.main.simulationSpace == ParticleSystemSimulationSpace.World && 0 < diff.sqrMagnitude) { Profiler.BeginSample("[UIParticle] Bake Mesh > Extra world simulation"); var count = currentPs.particleCount; if (s_Particles.Length < count) { var size = Mathf.NextPowerOfTwo(count); s_Particles = new ParticleSystem.Particle[size]; } currentPs.GetParticles(s_Particles); for (var j = 0; j < count; j++) { var p = s_Particles[j]; p.position += diff; s_Particles[j] = p; } currentPs.SetParticles(s_Particles, count); Profiler.EndSample(); } // #102: Do not bake particle system to mesh when the alpha is zero. if (Mathf.Approximately(particle.canvasRenderer.GetInheritedAlpha(), 0)) { continue; } // Bake main particles. var r = currentPs.GetComponent <ParticleSystemRenderer>(); if (CanBakeMesh(r)) { Profiler.BeginSample("[UIParticle] Bake Mesh > Bake Main Particles"); var hash = currentPs.GetMaterialHash(false); if (hash != 0) { var m = MeshHelper.GetTemporaryMesh(); r.BakeMesh(m, camera, true); MeshHelper.Push(i * 2, hash, m, matrix); } Profiler.EndSample(); } // Bake trails particles. if (currentPs.trails.enabled) { Profiler.BeginSample("[UIParticle] Bake Mesh > Bake Trails Particles"); var hash = currentPs.GetMaterialHash(true); if (hash != 0) { var m = MeshHelper.GetTemporaryMesh(); try { r.BakeTrailsMesh(m, camera, true); MeshHelper.Push(i * 2 + 1, hash, m, matrix); } catch { MeshHelper.DiscardTemporaryMesh(m); } } Profiler.EndSample(); } } // Set active indices. particle.activeMeshIndices = MeshHelper.activeMeshIndices; // Combine Profiler.BeginSample("[UIParticle] Bake Mesh > CombineMesh"); MeshHelper.CombineMesh(particle.bakedMesh); MeshHelper.Clear(); Profiler.EndSample(); }