Ejemplo n.º 1
0
        /// <summary>
        /// LateUpdate will prepare and call for calculations on each particle system.
        /// All threaded calculation is done after Update to ensure stable movement of particles.
        /// </summary>
        void LateUpdate()
        {
            activeThreads = 0;
            if (activeSystems.Count>0)
                activeSystems.Clear();
            frameCount++;
            isFirstUnsafeAutomaticFrames = frameCount<unsafeAutomaticThreadFrames||threadAggregatorRuns<unsafeAutomaticThreadFrames;
            if (reference!=this) {
                InitializePlayground();
                return;
            }

            // Update time
            SetTime();

            // Check the global event delegates for availability
            CheckEvents();

            // Prepare all global manipulators
            for (int m = 0; m<manipulators.Count; m++)
                manipulators[m].Update();

            // Return if no particle systems are available
            if (particleSystems.Count==0)
                return;

            hasActiveParticleSystems = false;
            hasLocalNoThreads = false;
            hasLocalOnePerSystem = false;
            hasLocalOneForAll = false;
            hasActiveSkinnedMeshes = false;
            hasActiveTurbulence = false;
            if (previousThreadMethod!=threadMethod) {
                isDoneThread = true;
                previousThreadMethod = threadMethod;
            }
            if (threadMethod!=ThreadMethod.OneForAll)
                isDoneThread = true;
            if (previousSkinnedMeshThreadMethod!=skinnedMeshThreadMethod) {
                isDoneThreadSkinned = true;
                previousSkinnedMeshThreadMethod = skinnedMeshThreadMethod;
            }
            if (previousTurbulenceThreadMethod!=turbulenceThreadMethod) {
                isDoneThreadTurbulence = true;
                previousTurbulenceThreadMethod = turbulenceThreadMethod;
            }

            // Prepare all particle systems
            Camera mainCamera = Camera.main;
            bool frustumPlanesSet = false;
            bool hasSourceUpdateNow = false;
            int currentParticleSystemCount = particleSystems.Count;
            for (int i = 0; i<particleSystems.Count; i++) {
                if (particleSystems[i]!=null &&
                    !particleSystems[i].isSnapshot &&
                    particleSystems[i].shurikenParticleSystem!=null &&
                    particleSystems[i].particleSystemGameObject.activeInHierarchy &&
                    particleSystems[i].Initialized() &&
                    !particleSystems[i].IsSettingParticleCount() &&
                    !particleSystems[i].IsSettingLifetime() &&
                    !particleSystems[i].IsYieldRefreshing() &&
                    !particleSystems[i].InTransition() &&
                    !particleSystems[i].IsLoading() &&
                    !particleSystems[i].IsPrewarming() &&
                    !particleSystems[i].IsSettingParticleTime()) {

                    // Catch up Shuriken particle lifetime with the update rate
                    if (Time.frameCount%particleSystems[i].updateRate!=0) {
                        for (int p = 0; p<particleSystems[i].particleCount; p++)
                            particleSystems[i].particleCache[p].lifetime = (particleSystems[i].playgroundCache.death[p]-particleSystems[i].playgroundCache.birth[p])-particleSystems[i].playgroundCache.lifetimeSubtraction[p];
                        particleSystems[i].isReadyForThreadedCalculations = false;
                        continue;
                    }

                    // Handle any system additions or removals
                    if (currentParticleSystemCount > particleSystems.Count) {
                        if (i>0) {
                            i--;
                            currentParticleSystemCount = particleSystems.Count;
                        } else {hasActiveParticleSystems=false; return;}
                    } else if (currentParticleSystemCount < particleSystems.Count) {
                        currentParticleSystemCount = particleSystems.Count;
                    }
                    if (particleSystems.Count==0 || i>=particleSystems.Count) {hasActiveParticleSystems=false; return;}

                    // Update the main camera frustum planes (this is used for culling particle systems)
                    if (!frustumPlanesSet && particleSystems[i].pauseCalculationWhenInvisible && mainCamera!=null && mainCamera.enabled) {
                        frustumPlanes = GeometryUtility.CalculateFrustumPlanes(mainCamera);
                        frustumPlanesSet = true;
                    }

                    // Update any particle system using onlySourcePositioning or onlyLifetimePositioning
                    if (particleSystems[i].onlySourcePositioning||particleSystems[i].onlyLifetimePositioning)
                        if (!particleSystems[i].UpdateSystem())
                            continue;

                    // Update any changes. Particle system may also be removed here.
                    if (particleSystems.Count>0 && i<particleSystems.Count) {

                        // Prepare for threaded calculations
                        particleSystems[i].isReadyForThreadedCalculations = particleSystems[i].PrepareThreadedCalculations();
                        if (particleSystems[i].IsAlive()) {
                            hasActiveParticleSystems = true;
                            if (particleSystems[i].onlySourcePositioning||particleSystems[i].onlyLifetimePositioning)
                                hasSourceUpdateNow = true;
                            if (threadMethod==ThreadMethod.Automatic)
                                activeSystems.Add (i);
                            if (!particleSystems[i].forceSkinnedMeshUpdateOnMainThread && particleSystems[i].IsSkinnedWorldObjectReady() && particleSystems[i].calculate)
                                hasActiveSkinnedMeshes = true;
                            if (particleSystems[i].HasTurbulence() && particleSystems[i].calculate)
                                hasActiveTurbulence = true;

                            switch (particleSystems[i].threadMethod) {
                                case ThreadMethodLocal.NoThreads:hasLocalNoThreads=true;break;
                                case ThreadMethodLocal.OnePerSystem:hasLocalOnePerSystem=true;break;
                                case ThreadMethodLocal.OneForAll:hasLocalOneForAll=true;break;
                            }
                        } else particleSystems[i].isReadyForThreadedCalculations = false;
                    } else if (particleSystems.Count>0 && i<particleSystems.Count && particleSystems[i]!=null) {
                        particleSystems[i].isReadyForThreadedCalculations = false;
                    }
                } else if (particleSystems[i]!=null) {
                    particleSystems[i].isReadyForThreadedCalculations = false;
                    if (particleSystems[i].IsPrewarming()) {
                        if (particleSystems[i].HasTurbulence()) {
                            hasActiveTurbulence = true;
                            hasActiveParticleSystems = true;
                        }
                    }
                }

            }

            // Proceed if we have any active particle systems
            if (hasActiveParticleSystems) {

                // Call for threaded calculations
                ThreadAggregator();

                // Call for immediate update on particle systems using onlySourcePositioning or onlyLifetimePositioning
                if (hasSourceUpdateNow) {
                    for (int i = 0; i<particleSystems.Count; i++) {
                        if (particleSystems[i]!=null &&
                            (particleSystems[i].onlySourcePositioning || particleSystems[i].onlyLifetimePositioning) &&
                            particleSystems[i].isReadyForThreadedCalculations &&
                            !particleSystems[i].InTransition() &&
                            !particleSystems[i].IsLoading() &&
                            particleSystems[i].IsReady()) {
                            particleSystems[i].UpdateShuriken();
                        }
                    }
                }
            }

            // Reset hierarchy repaint check
            #if UNITY_EDITOR
            PlaygroundParticlesC.didHierarchyRepaint = false;
            #endif
        }
Ejemplo n.º 2
0
        // Update is called both in Edit- and Play Mode once per frame
        void Update()
        {
            activeThreads = 0;
            frameCount++;
            isFirstUnsafeAutomaticFrames = frameCount<unsafeAutomaticThreadFrames||threadAggregatorRuns<unsafeAutomaticThreadFrames;
            if (reference!=this) {
                InitializePlayground();
                return;
            }

            // Update time
            SetTime();

            // Check the global event delegates for availability
            CheckEvents();

            // Prepare all global manipulators
            for (int m = 0; m<manipulators.Count; m++)
                manipulators[m].Update();

            // Return if no particle systems are available
            if (particleSystems.Count==0)
                return;

            hasActiveParticleSystems = false;
            hasLocalNoThreads = false;
            hasLocalOnePerSystem = false;
            hasLocalOneForAll = false;
            hasActiveSkinnedMeshes = false;
            hasActiveTurbulence = false;
            if (previousThreadMethod!=threadMethod) {
                isDoneThread = true;
                previousThreadMethod = threadMethod;
            }
            if (threadMethod!=ThreadMethod.OneForAll)
                isDoneThread = true;
            if (previousSkinnedMeshThreadMethod!=skinnedMeshThreadMethod) {
                isDoneThreadSkinned = true;
                previousSkinnedMeshThreadMethod = skinnedMeshThreadMethod;
            }
            if (previousTurbulenceThreadMethod!=turbulenceThreadMethod) {
                isDoneThreadTurbulence = true;
                previousTurbulenceThreadMethod = turbulenceThreadMethod;
            }

            // Prepare all particle systems
            int currentParticleSystemCount = particleSystems.Count;
            for (int i = 0; i<particleSystems.Count; i++) {
                if (particleSystems[i]!=null &&
                    particleSystems[i].calculate &&
                    !particleSystems[i].isSnapshot &&
                    particleSystems[i].shurikenParticleSystem!=null &&
                    particleSystems[i].particleSystemGameObject.activeInHierarchy &&
                    particleSystems[i].Initialized() &&
                    !particleSystems[i].IsSettingParticleCount() &&
                    !particleSystems[i].IsSettingLifetime() &&
                    !particleSystems[i].IsYieldRefreshing() &&
                    !particleSystems[i].InTransition() &&
                    !particleSystems[i].IsLoading() &&
                    Time.frameCount%particleSystems[i].updateRate==0) {

                    if (currentParticleSystemCount > particleSystems.Count) {
                        if (i>0) {
                            i--;
                            currentParticleSystemCount = particleSystems.Count;
                        } else return;
                    } else if (currentParticleSystemCount < particleSystems.Count) {
                        currentParticleSystemCount = particleSystems.Count;
                    }

                    if (particleSystems.Count==0 || i>=particleSystems.Count) return;

                    // Update any changes. Particle system may also be removed here.
                    if (particleSystems[i].UpdateSystem() && (particleSystems.Count>0 && i<particleSystems.Count)) {

                        // Prepare for threaded calculations
                        particleSystems[i].isReadyForThreadedCalculations = particleSystems[i].PrepareThreadedCalculations();
                        if (particleSystems[i].IsAlive()) {
                            hasActiveParticleSystems = true;
                            if (particleSystems[i].IsSkinnedWorldObjectReady())
                                hasActiveSkinnedMeshes = true;
                            if (particleSystems[i].HasTurbulence())
                                hasActiveTurbulence = true;

                            switch (particleSystems[i].threadMethod) {
                                case ThreadMethodLocal.NoThreads:hasLocalNoThreads=true;break;
                                case ThreadMethodLocal.OnePerSystem:hasLocalOnePerSystem=true;break;
                                case ThreadMethodLocal.OneForAll:hasLocalOneForAll=true;break;
                            }
                        } else particleSystems[i].isReadyForThreadedCalculations = false;
                    } else if (particleSystems.Count>0 && i<particleSystems.Count && particleSystems[i]!=null) {
                        particleSystems[i].isReadyForThreadedCalculations = false;
                    }
                } else if (particleSystems[i]!=null)
                    particleSystems[i].isReadyForThreadedCalculations = false;

            }

            // Call for threaded calculations
            if (hasActiveParticleSystems)
                ThreadAggregator();
        }