예제 #1
0
        /// <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;
            }
        }
예제 #2
0
        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
        }
예제 #4
0
 public static void Unregister(UIParticle particle)
 {
     if (!particle)
     {
         return;
     }
     s_ActiveParticles.Remove(particle);
 }
예제 #5
0
 public static void Register(UIParticle particle)
 {
     if (!particle)
     {
         return;
     }
     s_ActiveParticles.Add(particle);
 }
예제 #6
0
        /// <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);
        }
예제 #7
0
        /// <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);
            }
        }
예제 #8
0
 /// <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();
                 }
             }
         }
     }
 }
예제 #9
0
        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;
        }
예제 #10
0
        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();
        }