protected virtual void Awake()
 {
     if (!Object.op_Implicit((Object)this.spriteRenderer))
     {
         if (this.verboseDebug)
         {
             Debug.LogWarning((object)"Sprite Renderer not defined, trying to find in same GameObject");
         }
         this.spriteRenderer = (SpriteRenderer)((Component)this).GetComponent <SpriteRenderer>();
         if (!Object.op_Implicit((Object)this.spriteRenderer) && this.verboseDebug)
         {
             Debug.LogWarning((object)"Sprite Renderer not found");
         }
     }
     if (!Object.op_Implicit((Object)this.particlesSystem))
     {
         this.particlesSystem = (ParticleSystem)((Component)this).GetComponent <ParticleSystem>();
         if (!Object.op_Implicit((Object)this.particlesSystem))
         {
             if (!this.verboseDebug)
             {
                 return;
             }
             Debug.LogError((object)"No particle system found. Static Sprite Emission won't work");
             return;
         }
     }
     this.mainModule = this.particlesSystem.get_main();
     ((ParticleSystem.MainModule) ref this.mainModule).set_loop(false);
     ((ParticleSystem.MainModule) ref this.mainModule).set_playOnAwake(false);
     this.particlesSystem.Stop();
     this.SimulationSpace = ((ParticleSystem.MainModule) ref this.mainModule).get_simulationSpace();
 }
 protected override void ReadFromImpl(object obj)
 {
     base.ReadFromImpl(obj);
     ParticleSystem.VelocityOverLifetimeModule uo = (ParticleSystem.VelocityOverLifetimeModule)obj;
     enabled                  = uo.enabled;
     x                        = uo.x;
     y                        = uo.y;
     z                        = uo.z;
     xMultiplier              = uo.xMultiplier;
     yMultiplier              = uo.yMultiplier;
     zMultiplier              = uo.zMultiplier;
     orbitalX                 = uo.orbitalX;
     orbitalY                 = uo.orbitalY;
     orbitalZ                 = uo.orbitalZ;
     orbitalXMultiplier       = uo.orbitalXMultiplier;
     orbitalYMultiplier       = uo.orbitalYMultiplier;
     orbitalZMultiplier       = uo.orbitalZMultiplier;
     orbitalOffsetX           = uo.orbitalOffsetX;
     orbitalOffsetY           = uo.orbitalOffsetY;
     orbitalOffsetZ           = uo.orbitalOffsetZ;
     orbitalOffsetXMultiplier = uo.orbitalOffsetXMultiplier;
     orbitalOffsetYMultiplier = uo.orbitalOffsetYMultiplier;
     orbitalOffsetZMultiplier = uo.orbitalOffsetZMultiplier;
     radial                   = uo.radial;
     radialMultiplier         = uo.radialMultiplier;
     speedModifier            = uo.speedModifier;
     speedModifierMultiplier  = uo.speedModifierMultiplier;
     space                    = uo.space;
 }
Example #3
0
        private void SimulationSpaceAdjust(ParticleSystemSimulationSpace simulationSpace)
        {
            switch (simulationSpace)
            {
            case ParticleSystemSimulationSpace.Local:
            {
                targetTransform = transform;
                break;
            }

            case ParticleSystemSimulationSpace.Custom:
            {
                targetTransform = particleSystemMainModule.customSimulationSpace;
                break;
            }

            case ParticleSystemSimulationSpace.World:
            {
                targetTransform = transform;
                break;
            }

            default:
            {
                throw new System.NotSupportedException(string.Format("Unsupported simulation space '{0}'.",
                                                                     System.Enum.GetName(typeof(ParticleSystemSimulationSpace), particleSystemMainModule.simulationSpace)));
            }
            }
        }
        /// <summary>
        /// Starts the playback of this Playground Recorder with specified starting point, playback speed and if looping should occur.
        /// </summary>
        /// <param name="fromNormalizedTime">From normalized time in recording.</param>
        /// <param name="speed">The speed of the playback.</param>
        /// <param name="repeat">If set to <c>true</c> then enable looping.</param>
        public void Play(float fromNormalizedTime, float speed, bool repeat)
        {
            if (!_hasPlaygroundSystem)
            {
                return;
            }
            if (!_isReplaying && localSpaceOnPlayback)
            {
                _previousSimulationSpace = playgroundSystem.shurikenParticleSystem.simulationSpace;
                playgroundSystem.shurikenParticleSystem.simulationSpace = ParticleSystemSimulationSpace.Local;
            }

            playgroundSystem.inPlayback = true;
            playbackSpeed = speed;
            loopPlayback  = repeat;
            playHead      = fromNormalizedTime;
            _isReplaying  = true;
            StopRecording();
            StartPlayback();

            if (playHead >= 1f)
            {
                playHead = 0;
            }

            if (Application.isPlaying)
            {
                StartCoroutine(PlayRecordedFrames(playHead));
            }
        }
    private void OnTriggerStay(Collider collider)
    {
        if (!animator)
        {
            return;
        }

        if (collider.gameObject.CompareTag("Player") && animator.GetFloat(parameterHash) > 0.9f)
        {
            if (GameSceneManager.Instance && GameSceneManager.Instance.BloodParticles)
            {
                ParticleSystem system = GameSceneManager.Instance.BloodParticles;

                system.transform.position = transform.position;
                system.transform.rotation = Camera.main.transform.rotation;
                ParticleSystemSimulationSpace spaceMode = system.main.simulationSpace;
                spaceMode = ParticleSystemSimulationSpace.World;
                system.Emit(bloodParticlesBurstAmount);
            }

            if (gameSceneManager != null)
            {
                PlayerInfo info = gameSceneManager.GetPlayerInfo(collider.GetInstanceID());

                if (info != null && info.characterManager != null)
                {
                    info.characterManager.TakeDamage(damageAmount, doDamageSound && firstContact, doPainSound);
                }
            }

            firstContact = false;
        }
    }
Example #6
0
 protected virtual void Awake()
 {
     this.uiParticleSystem = (UIParticleRenderer)((Component)this).GetComponent <UIParticleRenderer>();
     if (!Object.op_Implicit((Object)this.imageRenderer))
     {
         if (this.verboseDebug)
         {
             Debug.LogWarning((object)"Image Renderer not defined, must be defined in order for the system to work");
         }
         this.isPlaying = false;
     }
     if (!Object.op_Implicit((Object)this.particlesSystem))
     {
         this.particlesSystem = (ParticleSystem)((Component)this).GetComponent <ParticleSystem>();
         if (!Object.op_Implicit((Object)this.particlesSystem))
         {
             if (!this.verboseDebug)
             {
                 return;
             }
             Debug.LogError((object)"No particle system found. Static Sprite Emission won't work");
             return;
         }
     }
     this.mainModule = this.particlesSystem.get_main();
     ((ParticleSystem.MainModule) ref this.mainModule).set_loop(false);
     ((ParticleSystem.MainModule) ref this.mainModule).set_playOnAwake(false);
     this.particlesSystem.Stop();
     this.SimulationSpace = ((ParticleSystem.MainModule) ref this.mainModule).get_simulationSpace();
 }
Example #7
0
    public static ParticleSystem SetSimulationSpace(this ParticleSystem ps, ParticleSystemSimulationSpace space)
    {
        var m = ps.main;

        m.simulationSpace = space;
        return(ps);
    }
 public static void ParticleVelocityOverTimeSettings(this ParticleSystem PS,
                                                     bool enabled = true,
                                                     ParticleSystemSimulationSpace space = ParticleSystemSimulationSpace.World,
                                                     float scalar     = 0.0f,
                                                     AnimationCurve X = null, // Set Externally
                                                     AnimationCurve Y = null, // Set Externally
                                                     AnimationCurve Z = null  // Set Externally
                                                     )
 {
     // Crashes for some reason
     //ParticleSystem.VelocityOverLifetimeModule velocityOverLifetimeModule = PS.velocityOverLifetime;
     //// Velocity Settings
     //velocityOverLifetimeModule.enabled = enabled;
     //velocityOverLifetimeModule.space = space;
     //if (X != null)
     //{
     //    ParticleSystem.MinMaxCurve VelocityCurveX = new ParticleSystem.MinMaxCurve(scalar, X);
     //    velocityOverLifetimeModule.x = VelocityCurveX;
     //}
     //if (Y != null)
     //{
     //    ParticleSystem.MinMaxCurve VelocityCurveY = new ParticleSystem.MinMaxCurve(scalar, Y);
     //    velocityOverLifetimeModule.y = VelocityCurveY;
     //}
     //if (Z != null)
     //{
     //    ParticleSystem.MinMaxCurve VelocityCurveZ = new ParticleSystem.MinMaxCurve(scalar, Z);
     //    velocityOverLifetimeModule.z = VelocityCurveZ;
     //}
 }
    static int IntToEnum(IntPtr L)
    {
        int arg0 = (int)LuaDLL.lua_tonumber(L, 1);
        ParticleSystemSimulationSpace o = (ParticleSystemSimulationSpace)arg0;

        LuaScriptMgr.PushEnum(L, o);
        return(1);
    }
    public override AIStateType OnUpdate()
    {
        timer += Time.deltaTime;
        if (zombieStateMachine.Satisfaction > 0.9f)
        {
            zombieStateMachine.GetWaypointPosition(false);
            return(AIStateType.Alerted);
        }

        if (zombieStateMachine.visualThreat.Type != AITargetType.None && zombieStateMachine.visualThreat.Type != AITargetType.VisualFood)
        {
            zombieStateMachine.SetTarget(zombieStateMachine.visualThreat);
            return(AIStateType.Alerted);
        }

        if (zombieStateMachine.audioThreat.Type == AITargetType.Audio)
        {
            zombieStateMachine.SetTarget(zombieStateMachine.audioThreat);
            return(AIStateType.Alerted);
        }

        int currentHash = zombieStateMachine.Animator.GetCurrentAnimatorStateInfo(eatingLayerIndex).shortNameHash;

        if (currentHash == eatingStateHash || currentHash == crawlEatingStateHash)
        {
            zombieStateMachine.Satisfaction = Mathf.Min(zombieStateMachine.Satisfaction + (Time.deltaTime * zombieStateMachine.ReplenishRate) / 100.0f, 1.0f);

            if (GameSceneManager.Instance && GameSceneManager.Instance.BloodParticles && bloodParticlesMount)
            {
                if (timer > bloodParticlesBurstTime)
                {
                    ParticleSystem system = GameSceneManager.Instance.BloodParticles;
                    system.transform.position = bloodParticlesMount.transform.position;
                    system.transform.rotation = bloodParticlesMount.transform.rotation;
                    ParticleSystemSimulationSpace spaceMode = system.main.simulationSpace;
                    spaceMode = ParticleSystemSimulationSpace.World;

                    system.Emit(bloodParticlesBurstAmount);
                    timer = 0.0f;
                }
            }
        }

        if (!zombieStateMachine.UseRootRotation)
        {
            Vector3 targetPos = zombieStateMachine.TargetPosition;
            targetPos.y = zombieStateMachine.transform.position.y;
            Quaternion newRot = Quaternion.LookRotation(targetPos - zombieStateMachine.transform.position);
            zombieStateMachine.transform.rotation = Quaternion.Slerp(zombieStateMachine.transform.rotation, newRot, Time.deltaTime * slerpSpeed);
        }

        Vector3 headToTarget = zombieStateMachine.TargetPosition - zombieStateMachine.Animator.GetBoneTransform(HumanBodyBones.Head).position;

        zombieStateMachine.transform.position = Vector3.Lerp(zombieStateMachine.transform.position, zombieStateMachine.transform.position + headToTarget, Time.deltaTime);

        return(AIStateType.Feeding);
    }
Example #11
0
 public static void SetSimulationSpace(ParticleSystem particleSystem, ParticleSystemSimulationSpace simulationSpace)
 {
     #if UNITY_5_5_OR_NEWER
     ParticleSystem.MainModule mainModule = particleSystem.main;
     mainModule.simulationSpace = simulationSpace;
     #else
     particleSystem.simulationSpace = simulationSpace;
     #endif
 }
        protected void Emit()
        {
            if (!this.hasCachingEnded)
            {
                return;
            }
            this.ParticlesToEmitThisFrame += this.EmissionRate * Time.get_deltaTime();
            Vector3    position   = ((Component)this.spriteRenderer).get_gameObject().get_transform().get_position();
            Vector3    vector3_1  = position;
            Quaternion rotation   = ((Component)this.spriteRenderer).get_gameObject().get_transform().get_rotation();
            Vector3    lossyScale = ((Component)this.spriteRenderer).get_gameObject().get_transform().get_lossyScale();
            ParticleSystemSimulationSpace simulationSpace = this.SimulationSpace;
            int   particlesCacheCount      = this.particlesCacheCount;
            float particleStartSize        = this.particleStartSize;
            int   particlesToEmitThisFrame = (int)this.ParticlesToEmitThisFrame;

            if (this.particlesCacheCount <= 0)
            {
                return;
            }
            Color[]   particleInitColorCache = this.particleInitColorCache;
            Vector3[] initPositionsCache     = this.particleInitPositionsCache;
            Vector3   zero = Vector3.get_zero();

            for (int index1 = 0; index1 < particlesToEmitThisFrame; ++index1)
            {
                int index2 = Random.Range(0, particlesCacheCount);
                if (this.useBetweenFramesPrecision)
                {
                    float num = Random.Range(0.0f, 1f);
                    vector3_1 = Vector3.Lerp(this.lastTransformPosition, position, num);
                }
                ParticleSystem.EmitParams emitParams = (ParticleSystem.EmitParams)null;
                if (this.UsePixelSourceColor)
                {
                    ((ParticleSystem.EmitParams) ref emitParams).set_startColor(Color32.op_Implicit(particleInitColorCache[index2]));
                }
                ((ParticleSystem.EmitParams) ref emitParams).set_startSize(particleStartSize);
                if (simulationSpace == 1)
                {
                    Vector3 vector3_2 = initPositionsCache[index2];
                    zero.x = vector3_2.x * lossyScale.x;
                    zero.y = vector3_2.y * lossyScale.y;
                    ((ParticleSystem.EmitParams) ref emitParams).set_position(Vector3.op_Addition(Quaternion.op_Multiply(rotation, zero), vector3_1));
                    this.particlesSystem.Emit(emitParams, 1);
                }
                else
                {
                    ((ParticleSystem.EmitParams) ref emitParams).set_position(initPositionsCache[index2]);
                    this.particlesSystem.Emit(emitParams, 1);
                }
            }
            this.ParticlesToEmitThisFrame -= (float)particlesToEmitThisFrame;
            this.lastTransformPosition     = position;
        }
        public void SetSimulation(ParticleSystemSimulationSpace space)
        {
            for (int i = 0; i < simulated.Length; i++)
            {
                simulated[i].Stop(true);

                var main = simulated[i].main;

                main.simulationSpace = space;

                simulated[i].Play(true);
            }
        }
 protected override void ReadFromImpl(object obj)
 {
     base.ReadFromImpl(obj);
     ParticleSystem.ForceOverLifetimeModule uo = (ParticleSystem.ForceOverLifetimeModule)obj;
     enabled     = uo.enabled;
     x           = uo.x;
     y           = uo.y;
     z           = uo.z;
     xMultiplier = uo.xMultiplier;
     yMultiplier = uo.yMultiplier;
     zMultiplier = uo.zMultiplier;
     space       = uo.space;
     randomized  = uo.randomized;
 }
        protected void Emit()
        {
            if (!this.hasCachingEnded)
            {
                return;
            }
            this.ParticlesToEmitThisFrame += this.EmissionRate * Time.get_deltaTime();
            Vector3    position   = ((Transform)this.currentRectTransform).get_position();
            Quaternion rotation   = ((Transform)this.currentRectTransform).get_rotation();
            Vector3    localScale = ((Transform)this.currentRectTransform).get_localScale();
            ParticleSystemSimulationSpace simulationSpace = this.SimulationSpace;
            int   particlesCacheCount      = this.particlesCacheCount;
            float particleStartSize        = this.particleStartSize;
            int   particlesToEmitThisFrame = (int)this.ParticlesToEmitThisFrame;

            if (this.particlesCacheCount <= 0)
            {
                return;
            }
            Color[]   particleInitColorCache = this.particleInitColorCache;
            Vector3[] initPositionsCache     = this.particleInitPositionsCache;
            Vector3   zero = Vector3.get_zero();

            for (int index1 = 0; index1 < particlesToEmitThisFrame; ++index1)
            {
                int index2 = Random.Range(0, particlesCacheCount);
                ParticleSystem.EmitParams emitParams = (ParticleSystem.EmitParams)null;
                if (this.UsePixelSourceColor)
                {
                    ((ParticleSystem.EmitParams) ref emitParams).set_startColor(Color32.op_Implicit(particleInitColorCache[index2]));
                }
                ((ParticleSystem.EmitParams) ref emitParams).set_startSize(particleStartSize);
                Vector3 vector3 = initPositionsCache[index2];
                if (simulationSpace == 1)
                {
                    zero.x = (__Null)(vector3.x * (double)this.wMult * localScale.x + this.offsetXY.x);
                    zero.y = (__Null)(vector3.y * (double)this.hMult * localScale.y - this.offsetXY.y);
                    ((ParticleSystem.EmitParams) ref emitParams).set_position(Vector3.op_Addition(Quaternion.op_Multiply(rotation, zero), position));
                    this.particlesSystem.Emit(emitParams, 1);
                }
                else
                {
                    zero.x = (__Null)(vector3.x * (double)this.wMult + this.offsetXY.x);
                    zero.y = (__Null)(vector3.y * (double)this.hMult - this.offsetXY.y);
                    ((ParticleSystem.EmitParams) ref emitParams).set_position(zero);
                    this.particlesSystem.Emit(emitParams, 1);
                }
            }
            this.ParticlesToEmitThisFrame -= (float)particlesToEmitThisFrame;
        }
Example #16
0
        //public enum RenderSystemUsing
        //{
        //    SpriteRenderer,
        //    ImageRenderer,
        //}
        //
        //protected RenderSystemUsing renderSystemUsing;
        /// <summary>
        /// Obtain needed references and define base variables.
        /// </summary>
        protected virtual void Awake()
        {
            //Find Renderer in current gameObject if non is draggued
            if (!spriteRenderer)
            {
                if (verboseDebug)
                {
                    Debug.LogWarning("Sprite Renderer not defined, trying to find in same GameObject");
                }
                spriteRenderer = GetComponent <SpriteRenderer>();
                if (!spriteRenderer)
                {
                    if (verboseDebug)
                    {
                        Debug.LogWarning("Sprite Renderer not found");
                    }
                }
            }

            //Find Particle System in current gameObject if non is draggued
            if (!particlesSystem)
            {
                particlesSystem = GetComponent <ParticleSystem>();
                if (!particlesSystem)
                {
                    if (verboseDebug)
                    {
                        Debug.LogError("No particle system found. Static Sprite Emission won't work");
                    }
                    return;
                }
            }

            //Set base varibles in the system for this emitter work as expected
            #if UNITY_5_5_OR_NEWER
            mainModule             = particlesSystem.main;
            mainModule.loop        = false;
            mainModule.playOnAwake = false;
            particlesSystem.Stop();
            //validate simulation Space
            SimulationSpace = mainModule.simulationSpace;
            #else
            particlesSystem.loop        = false;
            particlesSystem.playOnAwake = false;
            particlesSystem.Stop();
            //validate simulation Space
            SimulationSpace = particlesSystem.simulationSpace;
            #endif
        }
 protected override void ReadFromImpl(object obj)
 {
     base.ReadFromImpl(obj);
     ParticleSystem.MainModule uo = (ParticleSystem.MainModule)obj;
     duration                  = uo.duration;
     loop                      = uo.loop;
     prewarm                   = uo.prewarm;
     startDelay                = uo.startDelay;
     startDelayMultiplier      = uo.startDelayMultiplier;
     startLifetime             = uo.startLifetime;
     startLifetimeMultiplier   = uo.startLifetimeMultiplier;
     startSpeed                = uo.startSpeed;
     startSpeedMultiplier      = uo.startSpeedMultiplier;
     startSize3D               = uo.startSize3D;
     startSize                 = uo.startSize;
     startSizeMultiplier       = uo.startSizeMultiplier;
     startSizeX                = uo.startSizeX;
     startSizeXMultiplier      = uo.startSizeXMultiplier;
     startSizeY                = uo.startSizeY;
     startSizeYMultiplier      = uo.startSizeYMultiplier;
     startSizeZ                = uo.startSizeZ;
     startSizeZMultiplier      = uo.startSizeZMultiplier;
     startRotation3D           = uo.startRotation3D;
     startRotation             = uo.startRotation;
     startRotationMultiplier   = uo.startRotationMultiplier;
     startRotationX            = uo.startRotationX;
     startRotationXMultiplier  = uo.startRotationXMultiplier;
     startRotationY            = uo.startRotationY;
     startRotationYMultiplier  = uo.startRotationYMultiplier;
     startRotationZ            = uo.startRotationZ;
     startRotationZMultiplier  = uo.startRotationZMultiplier;
     flipRotation              = uo.flipRotation;
     startColor                = uo.startColor;
     gravityModifier           = uo.gravityModifier;
     gravityModifierMultiplier = uo.gravityModifierMultiplier;
     simulationSpace           = uo.simulationSpace;
     customSimulationSpace     = ToID(uo.customSimulationSpace);
     simulationSpeed           = uo.simulationSpeed;
     useUnscaledTime           = uo.useUnscaledTime;
     scalingMode               = uo.scalingMode;
     playOnAwake               = uo.playOnAwake;
     maxParticles              = uo.maxParticles;
     emitterVelocityMode       = uo.emitterVelocityMode;
     stopAction                = uo.stopAction;
     cullingMode               = uo.cullingMode;
     ringBufferMode            = uo.ringBufferMode;
     ringBufferLoopRange       = uo.ringBufferLoopRange;
 }
Example #18
0
        public ParticleData GetPositionByLife(float _normalizedLifeTime, ParticleSystemSimulationSpace _simulationSpace)
        {
            appliedNormalizedValue = _normalizedLifeTime * (pointArrayLenght);
            lowerPoint             = Mathf.FloorToInt(appliedNormalizedValue);

            if (highQualityFollow)
            {
                upperPoint = Mathf.Clamp(lowerPoint + 1, 0, pointArrayLenght);
                t          = Mathf.InverseLerp(lowerPoint, upperPoint, appliedNormalizedValue);

                if (_simulationSpace == ParticleSystemSimulationSpace.World)
                {
                    cacheReturnPoint = Vector3.Lerp(pointArrayWorld[lowerPoint], pointArrayWorld[upperPoint], t);
                }
                else
                {
                    cacheReturnPoint = Vector3.Lerp(pointArray[lowerPoint], pointArray[upperPoint], t);
                }

                if (updateSpeed)
                {
                    cacheParticleData.speed = Vector3.Lerp(speedAtPoint[lowerPoint], speedAtPoint[upperPoint], t);
                }
            }
            else
            {
                if (_simulationSpace == ParticleSystemSimulationSpace.World)
                {
                    cacheReturnPoint = pointArrayWorld[lowerPoint];
                }
                else
                {
                    cacheReturnPoint = pointArray[lowerPoint];
                }

                if (updateSpeed)
                {
                    cacheParticleData.speed = speedAtPoint[lowerPoint];
                }
            }

            cacheParticleData.position = cacheReturnPoint;

            return(cacheParticleData);
        }
Example #19
0
        /// <summary>
        /// Obtain needed references and define base variables.
        /// </summary>
        protected virtual void Awake()
        {
            uiParticleSystem = GetComponent <UIParticleRenderer>();

            //uiParticleSystem.GetComponent<UIParticleSystem>().hideFlags = HideFlags.HideInInspector;
            //Find Renderer in current gameObject if non is draggued
            if (!imageRenderer)
            {
                if (verboseDebug)
                {
                    Debug.LogWarning("Image Renderer not defined, must be defined in order for the system to work");
                }
                isPlaying = false;
            }

            //Find Particle System in current gameObject if non is draggued
            if (!particlesSystem)
            {
                particlesSystem = GetComponent <ParticleSystem>();
                if (!particlesSystem)
                {
                    if (verboseDebug)
                    {
                        Debug.LogError("No particle system found. Static Sprite Emission won't work");
                    }
                    return;
                }
            }

            //Set base varibles in the system for this emitter work as expected
            #if UNITY_5_5_OR_NEWER
            mainModule             = particlesSystem.main;
            mainModule.loop        = false;
            mainModule.playOnAwake = false;
            particlesSystem.Stop();
            //validate simulation Space
            SimulationSpace = mainModule.simulationSpace;
            #else
            particlesSystem.loop        = false;
            particlesSystem.playOnAwake = false;
            particlesSystem.Stop();
            //validate simulation Space
            SimulationSpace = particlesSystem.simulationSpace;
            #endif
        }
Example #20
0
        private void LateUpdate()
        {
            int maxParticles = particleSystemMainModule.maxParticles;

            if (particles == null || particles.Length < maxParticles)
            {
                particles = new ParticleSystem.Particle[maxParticles];
            }

            particleSystem.GetParticles(particles);
            int particlesCount = particleSystem.particleCount;

            float maxDistanceSqr = data.maxDistance * data.maxDistance;

            simulationSpace = particleSystemMainModule.simulationSpace;
            SimulationSpaceAdjust(simulationSpace);

            int lrIndex = 0;

            for (int i = 0; i < particlesCount; i++)
            {
                if (lrIndex >= data.maxLineRenderers)
                {
                    break;
                }
                connections = 0;
                ParticleSystem.Particle p1 = particles[i];

                for (int j = i + 1; j < particlesCount; j++)
                {
                    if (connections >= data.maxConnections || lrIndex >= data.maxLineRenderers)
                    {
                        break;
                    }

                    ParticleSystem.Particle p2 = particles[j];
                    lrIndex = SetupLineRenderer(maxDistanceSqr, lrIndex, p1, p2);
                }
            }

            for (int i = lrIndex; i < lineRenderers.Count; i++)
            {
                lineRenderers[i].enabled = false;
            }
        }
Example #21
0
 protected override void ReadFromImpl(object obj)
 {
     base.ReadFromImpl(obj);
     ParticleSystem.LimitVelocityOverLifetimeModule uo = (ParticleSystem.LimitVelocityOverLifetimeModule)obj;
     enabled                        = uo.enabled;
     limitX                         = uo.limitX;
     limitXMultiplier               = uo.limitXMultiplier;
     limitY                         = uo.limitY;
     limitYMultiplier               = uo.limitYMultiplier;
     limitZ                         = uo.limitZ;
     limitZMultiplier               = uo.limitZMultiplier;
     limit                          = uo.limit;
     limitMultiplier                = uo.limitMultiplier;
     dampen                         = uo.dampen;
     separateAxes                   = uo.separateAxes;
     space                          = uo.space;
     drag                           = uo.drag;
     dragMultiplier                 = uo.dragMultiplier;
     multiplyDragByParticleSize     = uo.multiplyDragByParticleSize;
     multiplyDragByParticleVelocity = uo.multiplyDragByParticleVelocity;
 }
        /// <summary>
        /// Emit particles based on EmissionRate.
        /// </summary>
        protected void Emit()
        {
            //safe check
            if (!hasCachingEnded)
            {
                return;
            }

            ParticlesToEmitThisFrame += EmissionRate * Time.deltaTime;

            //getting sprite source as gameobject for pos rot and scale
            Vector3    transformPos = spriteRenderer.gameObject.transform.position;
            Vector3    betweenFramesPrecisionPos = transformPos;
            Quaternion transformRot   = spriteRenderer.gameObject.transform.rotation;
            Vector3    transformScale = spriteRenderer.gameObject.transform.lossyScale;
            ParticleSystemSimulationSpace currentSimulationSpace = SimulationSpace;

            int   pCount        = particlesCacheCount;
            float pStartSize    = particleStartSize;
            int   EmissionCount = (int)ParticlesToEmitThisFrame;

            if (particlesCacheCount <= 0)
            {
                return;
            }

            //faster access
            Color[]   colorCache = particleInitColorCache;
            Vector3[] posCache   = particleInitPositionsCache;

            Vector3 tempV = Vector3.zero;

            for (int i = 0; i < EmissionCount; i++)
            {
                int rnd = Random.Range(0, pCount);
                if (useBetweenFramesPrecision)
                {
                    float randomDelta = Random.Range(0, 1f);
                    betweenFramesPrecisionPos = Vector3.Lerp(lastTransformPosition, transformPos, randomDelta);
                }

                ParticleSystem.EmitParams em = new ParticleSystem.EmitParams();
                if (UsePixelSourceColor)
                {
                    em.startColor = colorCache[rnd];
                }
                em.startSize = pStartSize;

                //if particles are set to World we must remove original particle calculation and apply the new transform modifiers.
                if (currentSimulationSpace == ParticleSystemSimulationSpace.World)
                {
                    Vector3 origPos = posCache[rnd];

                    tempV.x = origPos.x * transformScale.x;
                    tempV.y = origPos.y * transformScale.y;

                    em.position = transformRot * tempV + betweenFramesPrecisionPos;
                    particlesSystem.Emit(em, 1);
                }
                else
                {
                    em.position = posCache[rnd];
                    particlesSystem.Emit(em, 1);
                }
            }

            //sustract integer particles emitted and leave the float bit
            ParticlesToEmitThisFrame -= EmissionCount;
            lastTransformPosition     = transformPos;
        }
Example #23
0
    // Update is called once per frame
    void LateUpdate()
    {
        int maxParticles = particleSystemMainModule.maxParticles;

        if (particles == null || particles.Length < maxParticles)
        {
            particles = new ParticleSystem.Particle[maxParticles];
        }

        int lrIndex           = 0;
        int lineRendererCount = lineRenderers.Count;

        if (lineRendererCount > maxLineRendereres)
        {
            for (int i = maxLineRendereres; i < lineRendererCount; i++)
            {
                Destroy(lineRenderers[i].gameObject);
            }

            int removedCount = lineRendererCount - maxLineRendereres;
            lineRenderers.RemoveRange(maxLineRendereres, removedCount);
            lineRendererCount -= removedCount;
        }


        if (maxConnections > 0 && maxLineRendereres > 0)
        {
            particleSystem.GetParticles(particles);
            int particleCount = particleSystem.particleCount;

            float maxDistanceSqr = maxDistance * maxDistance;



            Vector3 p1_position, p2_position;

            ParticleSystemSimulationSpace simulationSpace = particleSystemMainModule.simulationSpace;

            switch (simulationSpace)
            {
            case ParticleSystemSimulationSpace.Local:
            {
                _transform = transform;

                break;
            }

            case ParticleSystemSimulationSpace.Custom:
            {
                _transform = particleSystemMainModule.customSimulationSpace;

                break;
            }

            case ParticleSystemSimulationSpace.World:
            {
                _transform = transform;

                break;
            }

            default:
            {
                throw new System.NotSupportedException(
                          string.Format("Unsupported Simulation Space '{0}'.", System.Enum.GetName(typeof(ParticleSystemSimulationSpace), particleSystemMainModule.simulationSpace)));
            }
            }
            for (int i = 0; i < particleCount; i++)
            {
                if (lrIndex >= maxLineRendereres)
                {
                    break;
                }
                p1_position = particles[i].position;

                int connections = 0;
                for (int j = i + 1; j < particleCount; j++)
                {
                    p2_position = particles[j].position;
                    float distanceSqr = Vector3.SqrMagnitude(p1_position - p2_position);

                    if (distanceSqr <= maxDistanceSqr)
                    {
                        LineRenderer lr;

                        if (lrIndex == lineRendererCount)
                        {
                            lr = Instantiate(lineRendererTemplate, _transform, false);
                            lineRenderers.Add(lr);

                            lineRendererCount++;
                        }

                        lr = lineRenderers[lrIndex];

                        lr.enabled       = true;
                        lr.useWorldSpace = simulationSpace == ParticleSystemSimulationSpace.World ? true : false;

                        lr.SetPosition(0, p1_position);
                        lr.SetPosition(1, p2_position);

                        lr.startColor = particles[i].color;
                        lr.endColor   = particles[j].color;


                        lrIndex++;
                        connections++;

                        if (connections >= maxConnections || lrIndex >= maxLineRendereres)
                        {
                            break;
                        }
                    }
                }
            }
        }

        for (int i = lrIndex; i < lineRendererCount; i++)
        {
            lineRenderers[i].enabled = false;
        }
    }
        /// <summary>
        /// Emit particles based on EmissionRate.
        /// </summary>
        protected void Emit()
        {
            //safe check
            if (!hasCachingEnded)
            {
                return;
            }

            ParticlesToEmitThisFrame += EmissionRate * Time.deltaTime;

            //getting sprite source as gameobject for pos rot and scale
            Vector3    transformPos   = currentRectTransform.position;
            Quaternion transformRot   = currentRectTransform.rotation;
            Vector3    transformScale = currentRectTransform.localScale;
            ParticleSystemSimulationSpace currentSimulationSpace = SimulationSpace;

            int   pCount        = particlesCacheCount;
            float pStartSize    = particleStartSize;
            int   EmissionCount = (int)ParticlesToEmitThisFrame;

            if (particlesCacheCount <= 0)
            {
                return;
            }

            //faster access
            Color[]   colorCache = particleInitColorCache;
            Vector3[] posCache   = particleInitPositionsCache;
            Vector3   tempV      = Vector3.zero;

            for (int i = 0; i < EmissionCount; i++)
            {
                int rnd = Random.Range(0, pCount);
                ParticleSystem.EmitParams em = new ParticleSystem.EmitParams();
                if (UsePixelSourceColor)
                {
                    em.startColor = colorCache[rnd];
                }
                em.startSize = pStartSize;

                Vector3 origPos = posCache[rnd];

                //if particles are set to World we must remove original particle calculation and apply the new transform modifiers.
                if (currentSimulationSpace == ParticleSystemSimulationSpace.World)
                {
                    tempV.x     = (origPos.x * wMult) * transformScale.x + offsetXY.x;
                    tempV.y     = (origPos.y * hMult) * transformScale.y - offsetXY.y;
                    em.position = transformRot * tempV + transformPos;
                    particlesSystem.Emit(em, 1);
                }
                else
                {
                    tempV.x     = (origPos.x * wMult) + offsetXY.x;
                    tempV.y     = (origPos.y * hMult) - offsetXY.y;
                    em.position = tempV;
                    particlesSystem.Emit(em, 1);
                }
            }

            //sustract integer particles emitted and leave the float bit
            ParticlesToEmitThisFrame -= EmissionCount;
        }
Example #25
0
                // ...

                void LateUpdate()
                {
                    if (trianglesMeshFilter)
                    {
                        switch (particleSystemMainModule.simulationSpace)
                        {
                        case ParticleSystemSimulationSpace.World:
                        {
                            // Make sure this is always at origin, or triangle mesh moves out of sync since
                            // the mesh triangle vertices are already set to the world space particle positions.

                            trianglesMeshFilter.transform.position = Vector3.zero;

                            break;
                        }

                        case ParticleSystemSimulationSpace.Local:
                        {
                            // In local space it should follow me.

                            trianglesMeshFilter.transform.position = transform.position;
                            trianglesMeshFilter.transform.rotation = transform.rotation;

                            break;
                        }

                        case ParticleSystemSimulationSpace.Custom:
                        {
                            // In custom space it should follow the custom transform.

                            trianglesMeshFilter.transform.position = particleSystemMainModule.customSimulationSpace.position;
                            trianglesMeshFilter.transform.rotation = particleSystemMainModule.customSimulationSpace.rotation;

                            break;
                        }
                        }
                    }

                    // Filter doesn't exist but mesh is there? That means the filter reference was lost. Clear the mesh.
                    // AKA... If mesh filter is gone (deleted and/or reference nulled), clear the mesh.

                    else if (trianglesMesh)
                    {
                        trianglesMesh.Clear();
                    }

                    int lineRenderersCount = lineRenderers.Count;

                    // In case max line renderers value is changed at runtime -> destroy extra.

                    if (lineRenderersCount > maxLineRenderers)
                    {
                        for (int i = maxLineRenderers; i < lineRenderersCount; i++)
                        {
                            Destroy(lineRenderers[i].gameObject);
                        }

                        lineRenderers.RemoveRange(maxLineRenderers, lineRenderersCount - maxLineRenderers);
                        //lineRendererData.RemoveRange(maxLineRenderers, lineRenderersCount - maxLineRenderers);

                        lineRenderersCount -= lineRenderersCount - maxLineRenderers;
                    }

                    if (alwaysUpdate || visible)
                    {
                        // Prevent constant allocations so long as max particle count doesn't change.

                        int maxParticles = particleSystemMainModule.maxParticles;

                        if (particles == null || particles.Length < maxParticles)
                        {
                            particles = new ParticleSystem.Particle[maxParticles];

                            particlePositions = new Vector3[maxParticles];

                            particleColours = new Color[maxParticles];
                            particleSizes   = new float[maxParticles];
                        }

                        float deltaTime = Time.deltaTime;

                        timer += deltaTime;

                        if (timer >= delay)
                        {
                            timer = 0.0f;

                            int lrIndex = 0;

                            allConnectedParticles.Clear();

                            // Only update if drawing/making connections.

                            if (maxConnections > 0 && maxLineRenderers > 0)
                            {
                                particleSystem.GetParticles(particles);
                                //particleSystem.GetCustomParticleData(customParticleData, ParticleSystemCustomData.Custom1);

                                int particleCount = particleSystem.particleCount;

                                float maxDistanceSqr = maxDistance * maxDistance;

                                ParticleSystemSimulationSpace simulationSpace = particleSystemMainModule.simulationSpace;
                                ParticleSystemScalingMode     scalingMode     = particleSystemMainModule.scalingMode;

                                Transform customSimulationSpaceTransform = particleSystemMainModule.customSimulationSpace;

                                Color lineRendererStartColour = lineRendererTemplate.startColor;
                                Color lineRendererEndColour   = lineRendererTemplate.endColor;

                                float lineRendererStartWidth = lineRendererTemplate.startWidth * lineRendererTemplate.widthMultiplier;
                                float lineRendererEndWidth   = lineRendererTemplate.endWidth * lineRendererTemplate.widthMultiplier;

                                // Save particle properties in a quick loop (accessing these is expensive and loops significantly more later, so it's better to save them once now).

                                for (int i = 0; i < particleCount; i++)
                                {
                                    particlePositions[i] = particles[i].position;

                                    particleColours[i] = particles[i].GetCurrentColor(particleSystem);
                                    particleSizes[i]   = particles[i].GetCurrentSize(particleSystem);

                                    // Default is 0.0f, so if default, this is a new particle and I need to assign a custom ID.

                                    //if (customParticleData[i].x == 0.0f)
                                    //{
                                    //    // ++value -> increment first, then return that value.
                                    //    // That way it won't be zero (default) the first time I use it.

                                    //    customParticleData[i] = new Vector4(++uniqueParticleID, 0, 0, 0);
                                    //}
                                }

                                //particleSystem.SetCustomParticleData(customParticleData, ParticleSystemCustomData.Custom1);

                                Vector3 p1p2_difference;

                                // If in world space, there's no need to do any of the extra calculations... simplify the loop!

                                if (simulationSpace == ParticleSystemSimulationSpace.World)
                                {
                                    for (int i = 0; i < particleCount; i++)
                                    {
                                        if (lrIndex == maxLineRenderers)
                                        {
                                            break;
                                        }

                                        Color particleColour = particleColours[i];

                                        Color lineStartColour = Color.LerpUnclamped(lineRendererStartColour, particleColour, colourFromParticle);
                                        float lineStartColourOriginalAlpha = Mathf.LerpUnclamped(lineRendererStartColour.a, particleColour.a, alphaFromParticle);

                                        lineStartColour.a = lineStartColourOriginalAlpha;

                                        float lineStartWidth = Mathf.LerpUnclamped(lineRendererStartWidth, particleSizes[i], widthFromParticle);

                                        int   connections        = 0;
                                        int[] connectedParticles = new int[maxConnections + 1];

                                        for (int j = i + 1; j < particleCount; j++)
                                        {
                                            p1p2_difference.x = particlePositions[i].x - particlePositions[j].x;
                                            p1p2_difference.y = particlePositions[i].y - particlePositions[j].y;
                                            p1p2_difference.z = particlePositions[i].z - particlePositions[j].z;

                                            //float distanceSqr = Vector3.SqrMagnitude(p1p2_difference);

                                            float distanceSqr =

                                                p1p2_difference.x * p1p2_difference.x +
                                                p1p2_difference.y * p1p2_difference.y +
                                                p1p2_difference.z * p1p2_difference.z;

                                            if (distanceSqr <= maxDistanceSqr)
                                            {
                                                LineRenderer lr;

                                                if (lrIndex == lineRenderersCount)
                                                {
                                                    lr = Instantiate(lineRendererTemplate, _transform, false);

                                                    lineRenderers.Add(lr);
                                                    lineRenderersCount++;
                                                }

                                                lr = lineRenderers[lrIndex]; lr.enabled = true;

                                                lr.SetPosition(0, particlePositions[i]);
                                                lr.SetPosition(1, particlePositions[j]);

                                                float alphaAttenuation = alphaOverNormalizedDistance.Evaluate(distanceSqr / maxDistanceSqr);
                                                lineStartColour.a = lineStartColourOriginalAlpha * alphaAttenuation;

                                                lr.startColor = lineStartColour;

                                                particleColour = particleColours[j];

                                                Color lineEndColour = Color.LerpUnclamped(lineRendererEndColour, particleColour, colourFromParticle);
                                                lineEndColour.a = Mathf.LerpUnclamped(lineRendererEndColour.a, particleColour.a, alphaFromParticle);

                                                lr.endColor = lineEndColour;

                                                lr.startWidth = lineStartWidth;
                                                lr.endWidth   = Mathf.LerpUnclamped(lineRendererEndWidth, particleSizes[j], widthFromParticle);

                                                lrIndex++;
                                                connections++;

                                                // Intentionally taken AFTER connections++ (because index = 0 is the i'th / line origin particle).

                                                connectedParticles[connections] = j;

                                                if (connections == maxConnections || lrIndex == maxLineRenderers)
                                                {
                                                    break;
                                                }
                                            }
                                        }

                                        if (connections >= 2)
                                        {
                                            connectedParticles[0] = i;
                                            allConnectedParticles.Add(connectedParticles);
                                        }
                                    }
                                }
                                else
                                {
                                    Vector3    position   = Vector3.zero;
                                    Quaternion rotation   = Quaternion.identity;
                                    Vector3    localScale = Vector3.one;

                                    Transform simulationSpaceTransform = _transform;

                                    switch (simulationSpace)
                                    {
                                    case ParticleSystemSimulationSpace.Local:
                                    {
                                        position   = simulationSpaceTransform.position;
                                        rotation   = simulationSpaceTransform.rotation;
                                        localScale = simulationSpaceTransform.localScale;

                                        break;
                                    }

                                    case ParticleSystemSimulationSpace.Custom:
                                    {
                                        simulationSpaceTransform = customSimulationSpaceTransform;

                                        position   = simulationSpaceTransform.position;
                                        rotation   = simulationSpaceTransform.rotation;
                                        localScale = simulationSpaceTransform.localScale;

                                        break;
                                    }

                                    default:
                                    {
                                        throw new System.NotSupportedException(

                                                  string.Format("Unsupported scaling mode '{0}'.", simulationSpace));
                                    }
                                    }

                                    // I put these here so I can take out the default exception case.
                                    // Else I'd have a compiler error for potentially unassigned variables.

                                    Vector3 p1_position = Vector3.zero;
                                    Vector3 p2_position = Vector3.zero;

                                    for (int i = 0; i < particleCount; i++)
                                    {
                                        if (lrIndex == maxLineRenderers)
                                        {
                                            break;
                                        }

                                        switch (simulationSpace)
                                        {
                                        case ParticleSystemSimulationSpace.Local:
                                        case ParticleSystemSimulationSpace.Custom:
                                        {
                                            switch (scalingMode)
                                            {
                                            case ParticleSystemScalingMode.Hierarchy:
                                            {
                                                p1_position = simulationSpaceTransform.TransformPoint(particlePositions[i]);

                                                break;
                                            }

                                            case ParticleSystemScalingMode.Local:
                                            {
                                                // Order is important.

                                                //p1_position = Vector3.Scale(particlePositions[i], localScale);

                                                p1_position.x = particlePositions[i].x * localScale.x;
                                                p1_position.y = particlePositions[i].y * localScale.y;
                                                p1_position.z = particlePositions[i].z * localScale.z;

                                                p1_position = rotation * p1_position;
                                                //p1_position += position;

                                                p1_position.x += position.x;
                                                p1_position.y += position.y;
                                                p1_position.z += position.z;

                                                break;
                                            }

                                            case ParticleSystemScalingMode.Shape:
                                            {
                                                // Order is important.

                                                p1_position = rotation * particlePositions[i];
                                                //p1_position += position;

                                                p1_position.x += position.x;
                                                p1_position.y += position.y;
                                                p1_position.z += position.z;

                                                break;
                                            }

                                            default:
                                            {
                                                throw new System.NotSupportedException(

                                                          string.Format("Unsupported scaling mode '{0}'.", scalingMode));
                                            }
                                            }

                                            break;
                                        }
                                        }

                                        Color particleColour = particleColours[i];

                                        Color lineStartColour = Color.LerpUnclamped(lineRendererStartColour, particleColour, colourFromParticle);
                                        float lineStartColourOriginalAlpha = Mathf.LerpUnclamped(lineRendererStartColour.a, particleColour.a, alphaFromParticle);

                                        lineStartColour.a = lineStartColourOriginalAlpha;

                                        float lineStartWidth = Mathf.LerpUnclamped(lineRendererStartWidth, particleSizes[i], widthFromParticle);

                                        int   connections        = 0;
                                        int[] connectedParticles = new int[maxConnections + 1];

                                        for (int j = i + 1; j < particleCount; j++)
                                        {
                                            // Note that because particles array is not sorted by distance,
                                            // but rather by spawn time (I think), the connections made are
                                            // not necessarily the closest.

                                            switch (simulationSpace)
                                            {
                                            case ParticleSystemSimulationSpace.Local:
                                            case ParticleSystemSimulationSpace.Custom:
                                            {
                                                switch (scalingMode)
                                                {
                                                case ParticleSystemScalingMode.Hierarchy:
                                                {
                                                    p2_position = simulationSpaceTransform.TransformPoint(particlePositions[j]);

                                                    break;
                                                }

                                                case ParticleSystemScalingMode.Local:
                                                {
                                                    // Order is important.

                                                    //p2_position = Vector3.Scale(particlePositions[j], localScale);

                                                    p2_position.x = particlePositions[j].x * localScale.x;
                                                    p2_position.y = particlePositions[j].y * localScale.y;
                                                    p2_position.z = particlePositions[j].z * localScale.z;

                                                    p2_position = rotation * p2_position;
                                                    //p2_position += position;

                                                    p2_position.x += position.x;
                                                    p2_position.y += position.y;
                                                    p2_position.z += position.z;

                                                    break;
                                                }

                                                case ParticleSystemScalingMode.Shape:
                                                {
                                                    // Order is important.

                                                    p2_position = rotation * particlePositions[j];
                                                    //p2_position += position;

                                                    p2_position.x += position.x;
                                                    p2_position.y += position.y;
                                                    p2_position.z += position.z;

                                                    break;
                                                }

                                                default:
                                                {
                                                    throw new System.NotSupportedException(

                                                              string.Format("Unsupported scaling mode '{0}'.", scalingMode));
                                                }
                                                }

                                                break;
                                            }
                                            }

                                            p1p2_difference.x = particlePositions[i].x - particlePositions[j].x;
                                            p1p2_difference.y = particlePositions[i].y - particlePositions[j].y;
                                            p1p2_difference.z = particlePositions[i].z - particlePositions[j].z;

                                            // Note that distance is always calculated in WORLD SPACE.
                                            // Scaling the particle system will stretch the distances
                                            // and may require adjusting the maxDistance value.

                                            // I could also do it in local space (which may actually make more
                                            // sense) by just getting the difference of the positions without
                                            // all the transformations. This also provides opportunity for
                                            // optimization as I can limit the world space transform calculations
                                            // to only happen if a particle is within range.

                                            // Think about: Putting in a bool to switch between the two?

                                            //float distanceSqr = Vector3.SqrMagnitude(p1p2_difference);

                                            float distanceSqr =

                                                p1p2_difference.x * p1p2_difference.x +
                                                p1p2_difference.y * p1p2_difference.y +
                                                p1p2_difference.z * p1p2_difference.z;

                                            // If distance to particle within range, add new vertex position.

                                            // The larger the max distance, the quicker connections will
                                            // reach its max, terminating the loop earlier. So even though more lines have
                                            // to be drawn, it's still faster to have a larger maxDistance value because
                                            // the call to Vector3.Distance() is expensive.

                                            if (distanceSqr <= maxDistanceSqr)
                                            {
                                                LineRenderer lr;

                                                if (lrIndex == lineRenderersCount)
                                                {
                                                    lr = Instantiate(lineRendererTemplate, _transform, false);

                                                    lineRenderers.Add(lr);
                                                    lineRenderersCount++;

                                                    //lineRendererData.Add(new LineRendererData());
                                                }

                                                lr = lineRenderers[lrIndex];
                                                //LineRendererData lrd = lineRendererData[lrIndex];

                                                lr.enabled = true;

                                                //lrd.previousStartParticleID = lrd.currentStartParticleID;
                                                //lrd.previousEndParticleID = lrd.currentEndParticleID;

                                                //lrd.currentStartParticleID = customParticleData[i].x;
                                                //lrd.currentEndParticleID = customParticleData[j].x;

                                                lr.SetPosition(0, p1_position);
                                                lr.SetPosition(1, p2_position);

                                                //if (lrd.currentStartParticleID != lrd.previousStartParticleID || lrd.currentEndParticleID != lrd.previousEndParticleID)
                                                //{
                                                //    lrd.timer = 0.0f;
                                                //}

                                                //if (lrd.timer < 1.0f)
                                                //{
                                                //    lrd.timer += deltaTime / fadeInTime;
                                                //}

                                                //if (lrd.timer > 1.0f)
                                                //{
                                                //    lrd.timer = 1.0f;
                                                //}

                                                float alphaAttenuation = alphaOverNormalizedDistance.Evaluate(distanceSqr / maxDistanceSqr);
                                                //float alphaAttenuation = lrd.timer * alphaOverNormalizedDistance.Evaluate(distanceSqr / maxDistanceSqr);

                                                lineStartColour.a = lineStartColourOriginalAlpha * alphaAttenuation;

                                                lr.startColor = lineStartColour;

                                                particleColour = particleColours[j];

                                                Color lineEndColour = Color.LerpUnclamped(lineRendererEndColour, particleColour, colourFromParticle);
                                                lineEndColour.a = Mathf.LerpUnclamped(lineRendererEndColour.a, particleColour.a, alphaFromParticle) * alphaAttenuation;

                                                lr.endColor = lineEndColour;

                                                lr.startWidth = lineStartWidth;
                                                lr.endWidth   = Mathf.LerpUnclamped(lineRendererEndWidth, particleSizes[j], widthFromParticle);

                                                //lineRendererData[lrIndex] = lrd;

                                                lrIndex++;
                                                connections++;

                                                // Intentionally taken AFTER connections++ (because index = 0 is the i'th / line origin particle).

                                                connectedParticles[connections] = j;

                                                if (connections == maxConnections || lrIndex == maxLineRenderers)
                                                {
                                                    break;
                                                }
                                            }
                                        }

                                        if (connections >= 2)
                                        {
                                            connectedParticles[0] = i;
                                            allConnectedParticles.Add(connectedParticles);
                                        }
                                    }
                                }
                            }

                            // Disable remaining line renderers from the pool that weren't used.

                            for (int i = lrIndex; i < lineRenderersCount; i++)
                            {
                                if (lineRenderers[i].enabled)
                                {
                                    lineRenderers[i].enabled = false;
                                }
                            }

                            // I check against the filter rather than the mesh because the mesh should always exist as long as the filter reference is there.
                            // This way I can stop drawing/updating should the filter reference be lost.

                            if (trianglesMeshFilter)
                            {
                                // Triangles mesh.

                                // For efficiency (and my own general laziness), I only bother taking the first triangle formed.
                                // It doesn't matter all that much since this is an abstract effect anyway.

                                int vertexCount = allConnectedParticles.Count * 3;

                                Vector3[] vertices  = new Vector3[vertexCount];
                                int[]     triangles = new int[vertexCount];

                                Vector2[] uv = new Vector2[vertexCount];

                                Color[] colours = new Color[vertexCount];

                                float maxDistanceSqr = (maxDistance * maxDistance) * maxDistanceTriangleBias;

                                for (int i = 0; i < allConnectedParticles.Count; i++)
                                {
                                    int[] connectedParticles = allConnectedParticles[i];

                                    float distanceSqr = 0.0f;

                                    if (trianglesDistanceCheck)
                                    {
                                        Vector3 particlePositionA = particlePositions[connectedParticles[1]];
                                        Vector3 particlePositionB = particlePositions[connectedParticles[2]];

                                        //distance = Vector3.Distance(particlePositionA, particlePositionB);

                                        Vector3 difference;

                                        difference.x = particlePositionA.x - particlePositionB.x;
                                        difference.y = particlePositionA.y - particlePositionB.y;
                                        difference.z = particlePositionA.z - particlePositionB.z;

                                        distanceSqr =

                                            difference.x * difference.x +
                                            difference.y * difference.y +
                                            difference.z * difference.z;
                                    }

                                    if (distanceSqr < maxDistanceSqr)
                                    {
                                        int i3 = i * 3;

                                        vertices[i3 + 0] = particlePositions[connectedParticles[0]];
                                        vertices[i3 + 1] = particlePositions[connectedParticles[1]];
                                        vertices[i3 + 2] = particlePositions[connectedParticles[2]];

                                        uv[i3 + 0] = new Vector2(0.0f, 0.0f);
                                        uv[i3 + 1] = new Vector2(0.0f, 1.0f);
                                        uv[i3 + 2] = new Vector2(1.0f, 1.0f);

                                        triangles[i3 + 0] = i3 + 0;
                                        triangles[i3 + 1] = i3 + 1;
                                        triangles[i3 + 2] = i3 + 2;

                                        colours[i3 + 0] = particleColours[connectedParticles[0]];
                                        colours[i3 + 1] = particleColours[connectedParticles[1]];
                                        colours[i3 + 2] = particleColours[connectedParticles[2]];

                                        colours[i3 + 0] = Color.LerpUnclamped(Color.white, particleColours[connectedParticles[0]], triangleColourFromParticle);
                                        colours[i3 + 1] = Color.LerpUnclamped(Color.white, particleColours[connectedParticles[1]], triangleColourFromParticle);
                                        colours[i3 + 2] = Color.LerpUnclamped(Color.white, particleColours[connectedParticles[2]], triangleColourFromParticle);

                                        colours[i3 + 0].a = Mathf.LerpUnclamped(1.0f, particleColours[connectedParticles[0]].a, triangleAlphaFromParticle);
                                        colours[i3 + 1].a = Mathf.LerpUnclamped(1.0f, particleColours[connectedParticles[1]].a, triangleAlphaFromParticle);
                                        colours[i3 + 2].a = Mathf.LerpUnclamped(1.0f, particleColours[connectedParticles[2]].a, triangleAlphaFromParticle);
                                    }
                                }

                                trianglesMesh.Clear();

                                trianglesMesh.vertices = vertices;

                                trianglesMesh.uv = uv;

                                trianglesMesh.triangles = triangles;
                                trianglesMesh.colors    = colours;
                            }
                        }
                    }
                }
                // ...

                protected virtual void LateUpdate()
                {
                    _radius   = scaledRadius;
                    radiusSqr = _radius * _radius;

                    forceDeltaTime    = force * Time.deltaTime;
                    transformPosition = transform.position + offset;

                    // SELECTIVE.
                    // If manually assigned a set of systems, use those no matter what.

                    if (_particleSystems.Count != 0)
                    {
                        // If editor array size changed, clear and add again.

                        if (particleSystems.Count != _particleSystems.Count)
                        {
                            particleSystems.Clear();
                            particleSystems.AddRange(_particleSystems);
                        }

                        // Else if array size is the same, then re-assign from
                        // the editor array. I do this in case the elements are different
                        // even though the size is the same.

                        else
                        {
                            for (int i = 0; i < _particleSystems.Count; i++)
                            {
                                particleSystems[i] = _particleSystems[i];
                            }
                        }
                    }

                    // LOCAL.
                    // Else if attached to particle system, use only that.
                    // Obviously, this will only happen if there are no systems specified in the array.

                    else if (particleSystem)
                    {
                        // If just one element, assign as local PS component.

                        if (particleSystems.Count == 1)
                        {
                            particleSystems[0] = particleSystem;
                        }

                        // Else, clear entire array and add only the one.

                        else
                        {
                            particleSystems.Clear();
                            particleSystems.Add(particleSystem);
                        }
                    }

                    // GLOBAL.
                    // Else, take all the ones from the entire scene.

                    // This is the most expensive since it searches the entire scene
                    // and also requires an allocation for every frame due to not knowing
                    // if the particle systems are all the same from the last frame unless
                    // I had a list to compare to from last frame. In that case, I'm not sure
                    // if the performance would be better or worse. Do a test later?

                    else
                    {
                        particleSystems.Clear();
                        particleSystems.AddRange(FindObjectsOfType <ParticleSystem>());
                    }

                    parameters = new GetForceParameters();

                    particleSystemsCount = particleSystems.Count;

                    // If first frame (array is null) or length is less than the number of systems, initialize size of array.
                    // I never shrink the array. Not sure if that's potentially super bad? I could always throw in a public
                    // bool as an option to allow shrinking since there's a performance benefit for each, but depends on the
                    // implementation case.

                    if (particleSystemParticles == null || particleSystemParticles.Length < particleSystemsCount)
                    {
                        particleSystemParticles   = new ParticleSystem.Particle[particleSystemsCount][];
                        particleSystemMainModules = new ParticleSystem.MainModule[particleSystemsCount];

                        particleSystemRenderers = new Renderer[particleSystemsCount];
                        particleSystemExternalForcesMultipliers = new float[particleSystemsCount];

                        for (int i = 0; i < particleSystemsCount; i++)
                        {
                            particleSystemMainModules[i] = particleSystems[i].main;
                            particleSystemRenderers[i]   = particleSystems[i].GetComponent <Renderer>();

                            particleSystemExternalForcesMultipliers[i] = particleSystems[i].externalForces.multiplier;
                        }
                    }

                    for (int i = 0; i < particleSystemsCount; i++)
                    {
                        if (!particleSystemRenderers[i].isVisible && !alwaysUpdate)
                        {
                            continue;
                        }

                        int maxParticles = particleSystemMainModules[i].maxParticles;

                        if (particleSystemParticles[i] == null || particleSystemParticles[i].Length < maxParticles)
                        {
                            particleSystemParticles[i] = new ParticleSystem.Particle[maxParticles];
                        }

                        currentParticleSystem = particleSystems[i];

                        PerParticleSystemSetup();

                        int particleCount = currentParticleSystem.GetParticles(particleSystemParticles[i]);

                        ParticleSystemSimulationSpace simulationSpace = particleSystemMainModules[i].simulationSpace;
                        ParticleSystemScalingMode     scalingMode     = particleSystemMainModules[i].scalingMode;

                        // I could also store the transforms in an array similar to what I do with modules.
                        // Or, put all of those together into a struct and make an array out of that since
                        // they'll always be assigned/updated at the same time.

                        Transform currentParticleSystemTransform = currentParticleSystem.transform;
                        Transform customSimulationSpaceTransform = particleSystemMainModules[i].customSimulationSpace;

                        // If in world space, there's no need to do any of the extra calculations... simplify the loop!

                        if (simulationSpace == ParticleSystemSimulationSpace.World)
                        {
                            for (int j = 0; j < particleCount; j++)
                            {
                                parameters.particlePosition = particleSystemParticles[i][j].position;

                                parameters.scaledDirectionToAffectorCenter.x = transformPosition.x - parameters.particlePosition.x;
                                parameters.scaledDirectionToAffectorCenter.y = transformPosition.y - parameters.particlePosition.y;
                                parameters.scaledDirectionToAffectorCenter.z = transformPosition.z - parameters.particlePosition.z;

                                parameters.distanceToAffectorCenterSqr = parameters.scaledDirectionToAffectorCenter.sqrMagnitude;

                                if (parameters.distanceToAffectorCenterSqr < radiusSqr)
                                {
                                    float distanceToCenterNormalized = parameters.distanceToAffectorCenterSqr / radiusSqr;
                                    float distanceScale = scaleForceByDistance.Evaluate(distanceToCenterNormalized);

                                    Vector3 force      = GetForce();
                                    float   forceScale = (forceDeltaTime * distanceScale) * particleSystemExternalForcesMultipliers[i];

                                    force.x *= forceScale;
                                    force.y *= forceScale;
                                    force.z *= forceScale;

                                    Vector3 particleVelocity = particleSystemParticles[i][j].velocity;

                                    particleVelocity.x += force.x;
                                    particleVelocity.y += force.y;
                                    particleVelocity.z += force.z;

                                    particleSystemParticles[i][j].velocity = particleVelocity;
                                }
                            }
                        }
                        else
                        {
                            Vector3    particleSystemPosition   = Vector3.zero;
                            Quaternion particleSystemRotation   = Quaternion.identity;
                            Vector3    particleSystemLocalScale = Vector3.one;

                            Transform simulationSpaceTransform = currentParticleSystemTransform;

                            switch (simulationSpace)
                            {
                            case ParticleSystemSimulationSpace.Local:
                            {
                                particleSystemPosition   = simulationSpaceTransform.position;
                                particleSystemRotation   = simulationSpaceTransform.rotation;
                                particleSystemLocalScale = simulationSpaceTransform.localScale;

                                break;
                            }

                            case ParticleSystemSimulationSpace.Custom:
                            {
                                simulationSpaceTransform = customSimulationSpaceTransform;

                                particleSystemPosition   = simulationSpaceTransform.position;
                                particleSystemRotation   = simulationSpaceTransform.rotation;
                                particleSystemLocalScale = simulationSpaceTransform.localScale;

                                break;
                            }

                            default:
                            {
                                throw new System.NotSupportedException(

                                          string.Format("Unsupported scaling mode '{0}'.", simulationSpace));
                            }
                            }

                            for (int j = 0; j < particleCount; j++)
                            {
                                parameters.particlePosition = particleSystemParticles[i][j].position;

                                switch (simulationSpace)
                                {
                                case ParticleSystemSimulationSpace.Local:
                                case ParticleSystemSimulationSpace.Custom:
                                {
                                    switch (scalingMode)
                                    {
                                    case ParticleSystemScalingMode.Hierarchy:
                                    {
                                        parameters.particlePosition = simulationSpaceTransform.TransformPoint(particleSystemParticles[i][j].position);

                                        break;
                                    }

                                    case ParticleSystemScalingMode.Local:
                                    {
                                        // Order is important.

                                        parameters.particlePosition = Vector3.Scale(parameters.particlePosition, particleSystemLocalScale);
                                        parameters.particlePosition = particleSystemRotation * parameters.particlePosition;
                                        parameters.particlePosition = parameters.particlePosition + particleSystemPosition;

                                        break;
                                    }

                                    case ParticleSystemScalingMode.Shape:
                                    {
                                        parameters.particlePosition = particleSystemRotation * parameters.particlePosition;
                                        parameters.particlePosition = parameters.particlePosition + particleSystemPosition;

                                        break;
                                    }

                                    default:
                                    {
                                        throw new System.NotSupportedException(

                                                  string.Format("Unsupported scaling mode '{0}'.", scalingMode));
                                    }
                                    }

                                    break;
                                }
                                }

                                parameters.scaledDirectionToAffectorCenter.x = transformPosition.x - parameters.particlePosition.x;
                                parameters.scaledDirectionToAffectorCenter.y = transformPosition.y - parameters.particlePosition.y;
                                parameters.scaledDirectionToAffectorCenter.z = transformPosition.z - parameters.particlePosition.z;

                                parameters.distanceToAffectorCenterSqr = parameters.scaledDirectionToAffectorCenter.sqrMagnitude;

                                //particleSystemParticles[i][j].velocity += forceDeltaTime * Vector3.Normalize(parameters.scaledDirectionToAffectorCenter);

                                if (parameters.distanceToAffectorCenterSqr < radiusSqr)
                                {
                                    // 0.0f -> 0.99...f;

                                    float distanceToCenterNormalized = parameters.distanceToAffectorCenterSqr / radiusSqr;

                                    // Evaluating a curve within a loop which is very likely to exceed a few thousand
                                    // iterations produces a noticeable FPS drop (around minus 2 - 5). Might be a worthwhile
                                    // optimization to check outside all loops if the curve is constant (all keyframes same value),
                                    // and then run a different block of code if true that uses that value as a stored float without
                                    // having to call Evaluate(t).

                                    float distanceScale = scaleForceByDistance.Evaluate(distanceToCenterNormalized);

                                    // Expanded vector operations for optimization. I think this is already done by
                                    // the compiler, but it's nice to have for the editor anyway.

                                    Vector3 force      = GetForce();
                                    float   forceScale = (forceDeltaTime * distanceScale) * particleSystemExternalForcesMultipliers[i];

                                    force.x *= forceScale;
                                    force.y *= forceScale;
                                    force.z *= forceScale;

                                    switch (simulationSpace)
                                    {
                                    case ParticleSystemSimulationSpace.Local:
                                    case ParticleSystemSimulationSpace.Custom:
                                    {
                                        switch (scalingMode)
                                        {
                                        case ParticleSystemScalingMode.Hierarchy:
                                        {
                                            force = simulationSpaceTransform.InverseTransformVector(force);

                                            break;
                                        }

                                        case ParticleSystemScalingMode.Local:
                                        {
                                            // Order is important.
                                            // Notice how rotation and scale orders are reversed.

                                            force = Quaternion.Inverse(particleSystemRotation) * force;
                                            force = Vector3.Scale(force, new Vector3(

                                                                      1.0f / particleSystemLocalScale.x,
                                                                      1.0f / particleSystemLocalScale.y,
                                                                      1.0f / particleSystemLocalScale.z));

                                            break;
                                        }

                                        case ParticleSystemScalingMode.Shape:
                                        {
                                            force = Quaternion.Inverse(particleSystemRotation) * force;

                                            break;
                                        }

                                        // This would technically never execute since it's checked earlier (above).

                                        default:
                                        {
                                            throw new System.NotSupportedException(

                                                      string.Format("Unsupported scaling mode '{0}'.", scalingMode));
                                        }
                                        }

                                        break;
                                    }
                                    }

                                    Vector3 particleVelocity = particleSystemParticles[i][j].velocity;

                                    particleVelocity.x += force.x;
                                    particleVelocity.y += force.y;
                                    particleVelocity.z += force.z;

                                    particleSystemParticles[i][j].velocity = particleVelocity;
                                }
                            }
                        }

                        currentParticleSystem.SetParticles(particleSystemParticles[i], particleCount);
                    }
                }
        protected override JSONObject ToJSON(WXHierarchyContext context)
        {
            ParticleSystemRenderer particleSystemRenderer = particleSys.GetComponent <ParticleSystemRenderer>();

            JSONObject json = new JSONObject(JSONObject.Type.OBJECT);
            JSONObject data = new JSONObject(JSONObject.Type.OBJECT);

            json.AddField("type", getTypeName());
            json.AddField("data", data);

            JSONObject materials = new JSONObject(JSONObject.Type.ARRAY);

            data.AddField("materials", materials);
            Material[] mats = particleSystemRenderer.sharedMaterials;
            foreach (Material material in mats)
            {
                if (material != null)
                {
                    WXMaterial materialConverter = new WXMaterial(material, particleSystemRenderer);
                    string     materialPath      = materialConverter.Export(context.preset);
                    materials.Add(materialPath);
                    context.AddResource(materialPath);
                }
            }

            JSONObject modCommon     = new JSONObject(JSONObject.Type.OBJECT);
            JSONObject modCommonData = new JSONObject(JSONObject.Type.OBJECT);

            data.AddField("common", modCommonData);

            modCommonData.AddField("startSize3D", particleSys.main.startSize3D);
            if (particleSys.main.startSize3D)
            {
                modCommonData.AddField("startSizeX", ParseMinMaxCurve(particleSys.main.startSizeX));
                modCommonData.AddField("startSizeY", ParseMinMaxCurve(particleSys.main.startSizeY));
                modCommonData.AddField("startSizeZ", ParseMinMaxCurve(particleSys.main.startSizeZ));
            }
            else
            {
                modCommonData.AddField("startSize", ParseMinMaxCurve(particleSys.main.startSize));
            }
            modCommonData.AddField("startColor", ParseMinMaxGradient(particleSys.main.startColor));
            modCommonData.AddField("startLifetime", ParseMinMaxCurve(particleSys.main.startLifetime));
            modCommonData.AddField("startRotation3D", particleSys.main.startRotation3D);
            if (particleSys.main.startRotation3D)
            {
                modCommonData.AddField("startRotationX", ParseMinMaxCurve(particleSys.main.startRotationX, (float)(180 / Math.PI)));
                modCommonData.AddField("startRotationY", ParseMinMaxCurve(particleSys.main.startRotationY, (float)(180 / Math.PI)));
                modCommonData.AddField("startRotationZ", ParseMinMaxCurve(particleSys.main.startRotationZ, (float)(180 / Math.PI)));
            }
            else
            {
                modCommonData.AddField("startRotationZ", ParseMinMaxCurve(particleSys.main.startRotation, (float)(180 / Math.PI)));
            }
            modCommonData.AddField("startSpeed", ParseMinMaxCurve(particleSys.main.startSpeed));
            modCommonData.AddField("gravityModifier", ParseMinMaxCurve(particleSys.main.gravityModifier));
#if UNITY_2018_1_OR_NEWER
            modCommonData.AddField("randomizeRotation", particleSys.main.flipRotation);
#endif
            modCommonData.AddField("randomSeed", particleSys.randomSeed);
            modCommonData.AddField("autoRandomSeed", particleSys.useAutoRandomSeed);

            ParticleSystemScalingMode pScalingMode = particleSys.main.scalingMode;
            int pScalingModeNum = 0;
            switch (pScalingMode)
            {
            case ParticleSystemScalingMode.Hierarchy:
                pScalingModeNum = 0;
                break;

            case ParticleSystemScalingMode.Local:
                pScalingModeNum = 1;
                break;

            case ParticleSystemScalingMode.Shape:
                pScalingModeNum = 2;
                break;
            }
            modCommonData.AddField("scalingMode", pScalingModeNum);

            ParticleSystemSimulationSpace simulationSpace = particleSys.main.simulationSpace;
            int simulationSpaceNum = 0;
            switch (simulationSpace)
            {
            case ParticleSystemSimulationSpace.Local:
                simulationSpaceNum = 0;
                break;

            case ParticleSystemSimulationSpace.World:
                simulationSpaceNum = 1;
                break;

            case ParticleSystemSimulationSpace.Custom:
                simulationSpaceNum = 2;
                break;
            }
            modCommonData.AddField("simulationSpace", simulationSpaceNum);

            JSONObject emitter     = new JSONObject(JSONObject.Type.OBJECT);
            JSONObject emitterData = new JSONObject(JSONObject.Type.OBJECT);
            data.AddField("emitter", emitterData);
            emitterData.AddField("playOnAwake", particleSys.main.playOnAwake);
            emitterData.AddField("looping", particleSys.main.loop);
            emitterData.AddField("duration", particleSys.main.duration);
            emitterData.AddField("startDelay", ParseMinMaxCurve(particleSys.main.startDelay));


            if (particleSys.emission.enabled)
            {
                JSONObject burst = new JSONObject(JSONObject.Type.ARRAY);
                emitterData.AddField("bursts", burst);
                int count = particleSys.emission.burstCount;
                ParticleSystem.Burst[] bursts = new ParticleSystem.Burst[count];
                particleSys.emission.GetBursts(bursts);
                for (int i = 0; i < count; i++)
                {
                    //burst.Add(ParseBurst(particleSys.emission.GetBurst(i)));
                    burst.Add(ParseBurst(bursts[i]));
                }

                emitterData.AddField("rateOverTime", ParseMinMaxCurve(particleSys.emission.rateOverTime));
            }
            emitterData.AddField("maxParticles", particleSys.main.maxParticles);

            if (particleSystemRenderer.enabled)
            {
                JSONObject renderer     = new JSONObject(JSONObject.Type.OBJECT);
                JSONObject rendererData = new JSONObject(JSONObject.Type.OBJECT);
                data.AddField("renderer", rendererData);
                ParticleSystemRenderMode pRenderMode = particleSystemRenderer.renderMode;
                int pRenderModeNum = 0;
                switch (pRenderMode)
                {
                case ParticleSystemRenderMode.Billboard:
                    pRenderModeNum = 1;
                    break;

                case ParticleSystemRenderMode.Stretch:
                    pRenderModeNum = 2;
                    rendererData.AddField("cameraScale", particleSystemRenderer.cameraVelocityScale);
                    rendererData.AddField("speedScale", particleSystemRenderer.velocityScale);
                    rendererData.AddField("lengthScale", particleSystemRenderer.lengthScale);
                    break;

                case ParticleSystemRenderMode.HorizontalBillboard:
                    pRenderModeNum = 3;
                    break;

                case ParticleSystemRenderMode.VerticalBillboard:
                    pRenderModeNum = 4;
                    break;

                case ParticleSystemRenderMode.Mesh:
                    Mesh mesh = particleSystemRenderer.mesh;
                    if (mesh != null)
                    {
                        WXMesh meshConverter = new WXMesh(mesh);
                        string meshPath      = meshConverter.Export(context.preset);
                        rendererData.AddField("mesh", meshPath);
                        rendererData.AddField("meshCount", particleSystemRenderer.meshCount);
                        context.AddResource(meshPath);
                    }
                    else
                    {
                        Debug.LogError(string.Format("{0} mesh is null", particleSys.name));
                    }
                    pRenderModeNum = 5;
                    break;

                case ParticleSystemRenderMode.None:
                    pRenderModeNum = 0;
                    break;

                default:
                    pRenderModeNum = 1;
                    break;
                }
                rendererData.AddField("renderMode", pRenderModeNum);

                int mode = 1;
                switch (particleSystemRenderer.alignment)
                {
                case ParticleSystemRenderSpace.View:
                    mode = 1;
                    break;

                case ParticleSystemRenderSpace.World:
                    mode = 2;
                    break;

                case ParticleSystemRenderSpace.Local:
                    mode = 3;
                    break;

                case ParticleSystemRenderSpace.Facing:
                    mode = 4;
                    break;

#if UNITY_2017_1_OR_NEWER
                case ParticleSystemRenderSpace.Velocity:
                    mode = 5;
                    break;
#endif
                default:
                    break;
                }
                rendererData.AddField("renderAlignment", mode);


                mode = 0;
                switch (particleSystemRenderer.sortMode)
                {
                case ParticleSystemSortMode.None:
                    mode = 0;
                    break;

                case ParticleSystemSortMode.Distance:
                    mode = 1;
                    break;

                case ParticleSystemSortMode.OldestInFront:
                    mode = 2;
                    break;

                case ParticleSystemSortMode.YoungestInFront:
                    mode = 3;
                    break;

                default:
                    break;
                }
                rendererData.AddField("sortMode", mode);
                rendererData.AddField("sortingFudge", particleSystemRenderer.sortingFudge);
                rendererData.AddField("normalDirection", particleSystemRenderer.normalDirection);
                rendererData.AddField("minParticleSize", particleSystemRenderer.minParticleSize);
                rendererData.AddField("maxParticleSize", particleSystemRenderer.maxParticleSize);

                var flipValue = TryGetContainProperty(particleSystemRenderer, "flip");
                if (flipValue != null)
                {
                    rendererData.AddField("flip", GetVect3((Vector3)flipValue));
                }
                else
                {
                    renderer.AddField("flip", GetVect3(new Vector3(0, 0, 0)));
                }
                //rendererData.AddField("flip", GetVect3(particleSystemRenderer.flip));
                rendererData.AddField("pivot", GetVect3(particleSystemRenderer.pivot));

                var allowRollData = TryGetContainProperty(particleSystemRenderer, "allowRoll");
                if (allowRollData != null)
                {
                    rendererData.AddField("allowRoll", (bool)allowRollData);
                }
                else
                {
                    rendererData.AddField("allowRoll", false);
                }
            }
            else
            {
                String info = "entity: " + particleSys.gameObject.name + " 的粒子组件没有renderer模块,不可导出;请加上renderer模块,或删除该粒子组件";

                ErrorUtil.ExportErrorReporter.create()
                .setGameObject(particleSys.gameObject)
                .setHierarchyContext(context)
                .error(0, "粒子组件没有renderer模块,不可导出;请加上renderer模块,或删除该粒子组件");
            }

            if (particleSys.rotationOverLifetime.enabled)
            {
                JSONObject rotationByLife     = new JSONObject(JSONObject.Type.OBJECT);
                JSONObject rotationByLifeData = new JSONObject(JSONObject.Type.OBJECT);
                data.AddField("rotationByLife", rotationByLifeData);

                rotationByLifeData.AddField("separateAxes", particleSys.rotationOverLifetime.separateAxes);
                if (particleSys.rotationOverLifetime.separateAxes)
                {
                    rotationByLifeData.AddField("x", ParseMinMaxCurve(particleSys.rotationOverLifetime.x, (float)(180 / Math.PI)));
                    rotationByLifeData.AddField("y", ParseMinMaxCurve(particleSys.rotationOverLifetime.y, (float)(180 / Math.PI)));
                    rotationByLifeData.AddField("z", ParseMinMaxCurve(particleSys.rotationOverLifetime.z, (float)(180 / Math.PI)));
                }
                else
                {
                    rotationByLifeData.AddField("z", ParseMinMaxCurve(particleSys.rotationOverLifetime.z, (float)(180 / Math.PI)));
                }
            }

            if (particleSys.sizeOverLifetime.enabled)
            {
                JSONObject sizeOverLifetime     = new JSONObject(JSONObject.Type.OBJECT);
                JSONObject sizeOverLifetimeData = new JSONObject(JSONObject.Type.OBJECT);
                data.AddField("sizeByLife", sizeOverLifetimeData);

                sizeOverLifetimeData.AddField("separateAxes", particleSys.sizeOverLifetime.separateAxes);
                if (particleSys.sizeOverLifetime.separateAxes)
                {
                    sizeOverLifetimeData.AddField("x", ParseMinMaxCurve(particleSys.sizeOverLifetime.x));
                    sizeOverLifetimeData.AddField("y", ParseMinMaxCurve(particleSys.sizeOverLifetime.y));
                    sizeOverLifetimeData.AddField("z", ParseMinMaxCurve(particleSys.sizeOverLifetime.z));
                }
                else
                {
                    sizeOverLifetimeData.AddField("x", ParseMinMaxCurve(particleSys.sizeOverLifetime.size));
                }
            }

            if (particleSys.velocityOverLifetime.enabled)
            {
                JSONObject speedByLifeData = new JSONObject(JSONObject.Type.OBJECT);
                data.AddField("speedByLife", speedByLifeData);
                switch (particleSys.velocityOverLifetime.space)
                {
                case ParticleSystemSimulationSpace.Local:
                    speedByLifeData.AddField("space", 1);
                    break;

                case ParticleSystemSimulationSpace.World:
                    speedByLifeData.AddField("space", 2);
                    break;

                case ParticleSystemSimulationSpace.Custom:
                    break;

                default:
                    break;
                }

                speedByLifeData.AddField("x", ParseMinMaxCurve(particleSys.velocityOverLifetime.x));
                speedByLifeData.AddField("y", ParseMinMaxCurve(particleSys.velocityOverLifetime.y));
                speedByLifeData.AddField("z", ParseMinMaxCurve(particleSys.velocityOverLifetime.z));
#if UNITY_2018_1_OR_NEWER
                speedByLifeData.AddField("orbitalX", ParseMinMaxCurve(particleSys.velocityOverLifetime.orbitalX));
                speedByLifeData.AddField("orbitalY", ParseMinMaxCurve(particleSys.velocityOverLifetime.orbitalY));
                speedByLifeData.AddField("orbitalZ", ParseMinMaxCurve(particleSys.velocityOverLifetime.orbitalZ));
                speedByLifeData.AddField("orbitalOffsetX", ParseMinMaxCurve(particleSys.velocityOverLifetime.orbitalOffsetX));
                speedByLifeData.AddField("orbitalOffsetY", ParseMinMaxCurve(particleSys.velocityOverLifetime.orbitalOffsetY));
                speedByLifeData.AddField("orbitalOffsetZ", ParseMinMaxCurve(particleSys.velocityOverLifetime.orbitalOffsetZ));
                speedByLifeData.AddField("radial", ParseMinMaxCurve(particleSys.velocityOverLifetime.radial));
#endif
#if UNITY_2017_1_OR_NEWER
                speedByLifeData.AddField("speedScale", ParseMinMaxCurve(particleSys.velocityOverLifetime.speedModifier));
#endif
            }

            if (particleSys.limitVelocityOverLifetime.enabled)
            {
                JSONObject speedLimitByLifeData = new JSONObject(JSONObject.Type.OBJECT);
                data.AddField("speedLimitByLife", speedLimitByLifeData);
                speedLimitByLifeData.AddField("separateAxes", particleSys.limitVelocityOverLifetime.separateAxes);
                if (particleSys.limitVelocityOverLifetime.separateAxes)
                {
                    speedLimitByLifeData.AddField("x", ParseMinMaxCurve(particleSys.limitVelocityOverLifetime.limitX, particleSys.limitVelocityOverLifetime.limitXMultiplier));
                    speedLimitByLifeData.AddField("y", ParseMinMaxCurve(particleSys.limitVelocityOverLifetime.limitY, particleSys.limitVelocityOverLifetime.limitYMultiplier));
                    speedLimitByLifeData.AddField("z", ParseMinMaxCurve(particleSys.limitVelocityOverLifetime.limitZ, particleSys.limitVelocityOverLifetime.limitZMultiplier));
                }
                else
                {
                    speedLimitByLifeData.AddField("x", ParseMinMaxCurve(particleSys.limitVelocityOverLifetime.limit, particleSys.limitVelocityOverLifetime.limitMultiplier));
                }
                speedLimitByLifeData.AddField("dampen", particleSys.limitVelocityOverLifetime.dampen);
                switch (particleSys.limitVelocityOverLifetime.space)
                {
                case ParticleSystemSimulationSpace.Local:
                    speedLimitByLifeData.AddField("space", 1);
                    break;

                case ParticleSystemSimulationSpace.World:
                    speedLimitByLifeData.AddField("space", 2);
                    break;

                case ParticleSystemSimulationSpace.Custom:
                    break;

                default:
                    break;
                }
#if UNITY_2017_1_OR_NEWER
                speedLimitByLifeData.AddField("drag", ParseMinMaxCurve(particleSys.limitVelocityOverLifetime.drag));
                speedLimitByLifeData.AddField("dragMultiplyBySize", particleSys.limitVelocityOverLifetime.multiplyDragByParticleSize);
                speedLimitByLifeData.AddField("dragMultiplyBySpeed", particleSys.limitVelocityOverLifetime.multiplyDragByParticleVelocity);
#endif
            }

            if (particleSys.colorOverLifetime.enabled)
            {
                JSONObject colorOverLifetime     = new JSONObject(JSONObject.Type.OBJECT);
                JSONObject colorOverLifetimeData = new JSONObject(JSONObject.Type.OBJECT);
                data.AddField("colorByLife", colorOverLifetimeData);
                colorOverLifetimeData.AddField("gColor", ParseMinMaxGradient(particleSys.colorOverLifetime.color));
            }

            if (particleSys.shape.enabled)
            {
                JSONObject shapeData = new JSONObject(JSONObject.Type.OBJECT);
                var        haveShape = true;
                if (particleSys.shape.shapeType == ParticleSystemShapeType.Cone || particleSys.shape.shapeType == ParticleSystemShapeType.ConeVolume || particleSys.shape.shapeType == ParticleSystemShapeType.ConeVolumeShell || particleSys.shape.shapeType == ParticleSystemShapeType.ConeShell)
                {
                    shapeData.AddField("shape", ParseConeShape(particleSys.shape));
                }
                else if (particleSys.shape.shapeType == ParticleSystemShapeType.Sphere || particleSys.shape.shapeType == ParticleSystemShapeType.SphereShell)
                {
                    shapeData.AddField("shape", ParseSphereShape(particleSys.shape));
                }
                else if (particleSys.shape.shapeType == ParticleSystemShapeType.Circle || particleSys.shape.shapeType == ParticleSystemShapeType.CircleEdge)
                {
                    shapeData.AddField("shape", ParseCircleShape(particleSys.shape));
                }
                else if (particleSys.shape.shapeType == ParticleSystemShapeType.Box || particleSys.shape.shapeType == ParticleSystemShapeType.BoxEdge || particleSys.shape.shapeType == ParticleSystemShapeType.BoxShell)
                {
                    shapeData.AddField("shape", ParseBox(particleSys.shape));
                }
                else if (particleSys.shape.shapeType == ParticleSystemShapeType.Hemisphere || particleSys.shape.shapeType == ParticleSystemShapeType.HemisphereShell)
                {
                    shapeData.AddField("shape", ParseHemisphere(particleSys.shape));
                }
                // else if (particleSys.shape.shapeType == ParticleSystemShapeType.SingleSidedEdge) {
                //     shapeData.AddField("shape", ParseSingleSidedEdge(particleSys.shape));
                // }
                else
                {
                    var parentChain = go.name;
                    var parent      = go.transform.parent;
                    while (parent)
                    {
                        parentChain += " -> " + parent.gameObject.name;
                        parent       = parent.parent;
                    }
                    Debug.LogError("unSupport shape (" + particleSys.shape.shapeType.ToString() + ") at: " + parentChain);
                    haveShape = false;
                }
                if (haveShape)
                {
                    data.AddField("emitterShape", shapeData);
                }
            }

            if (particleSys.textureSheetAnimation.enabled)
            {
                JSONObject textureSheetAnimationData = new JSONObject(JSONObject.Type.OBJECT);
                data.AddField("textureSheetAnimation", textureSheetAnimationData);
                int mode = 1;
#if UNITY_2017_1_OR_NEWER
                mode = 1;
                switch (particleSys.textureSheetAnimation.mode)
                {
                case ParticleSystemAnimationMode.Grid:
                    mode = 1;
                    break;

                case ParticleSystemAnimationMode.Sprites:
                    mode = 2;
                    break;

                default:
                    break;
                }
                textureSheetAnimationData.AddField("mode", mode);
#endif
                JSONObject vec2 = new JSONObject(JSONObject.Type.ARRAY);
                vec2.Add(particleSys.textureSheetAnimation.numTilesX);
                vec2.Add(particleSys.textureSheetAnimation.numTilesY);
                textureSheetAnimationData.AddField("tiles", vec2);
                mode = 1;
                switch (particleSys.textureSheetAnimation.animation)
                {
                case ParticleSystemAnimationType.WholeSheet:
                    mode = 1;
                    break;

                case ParticleSystemAnimationType.SingleRow:
                    mode = 2;
                    break;

                default:
                    break;
                }
                textureSheetAnimationData.AddField("animationType", mode);
                textureSheetAnimationData.AddField("randomRow", particleSys.textureSheetAnimation.useRandomRow);
                textureSheetAnimationData.AddField("row", particleSys.textureSheetAnimation.rowIndex);

                //mode = 1;
                //switch (particleSys.textureSheetAnimation.timeMode)
                //{
                //    case ParticleSystemAnimationTimeMode.Lifetime:
                //        mode = 1;
                //        break;
                //    case ParticleSystemAnimationTimeMode.Speed:
                //        mode = 2;
                //        break;
                //    case ParticleSystemAnimationTimeMode.FPS:
                //        mode = 3;
                //        break;
                //    default:
                //        break;
                //}
                textureSheetAnimationData.AddField("timeMode", 1);
                if (mode == 1)
                {
                    textureSheetAnimationData.AddField("frameOverTime", ParseMinMaxCurve(particleSys.textureSheetAnimation.frameOverTime, particleSys.textureSheetAnimation.numTilesX * particleSys.textureSheetAnimation.numTilesY));
                }
                else
                {
                    textureSheetAnimationData.AddField("frameOverTime", ParseMinMaxCurve(particleSys.textureSheetAnimation.frameOverTime, particleSys.textureSheetAnimation.numTilesX));
                }
                textureSheetAnimationData.AddField("startFrame", ParseMinMaxCurve(particleSys.textureSheetAnimation.startFrame));
                textureSheetAnimationData.AddField("cycles", particleSys.textureSheetAnimation.cycleCount);
                mode = 0;
                var a = particleSys.textureSheetAnimation.uvChannelMask;
                var b = a & UVChannelFlags.UV0;
                if ((a & UVChannelFlags.UV0) != 0)
                {
                    mode += 1;
                }
                if ((a & UVChannelFlags.UV1) != 0)
                {
                    mode += 2;
                }
                if ((a & UVChannelFlags.UV2) != 0)
                {
                    mode += 3;
                }
                if ((a & UVChannelFlags.UV3) != 0)
                {
                    mode += 4;
                }

                textureSheetAnimationData.AddField("affectedUVChannels", mode);
            }

            if (particleSys.subEmitters.enabled)
            {
                JSONObject subEmittersData = new JSONObject(JSONObject.Type.ARRAY);
                data.AddField("subEmitters", subEmittersData);

                int count = particleSys.subEmitters.subEmittersCount;
                for (int i = 0; i < count; i++)
                {
                    ParticleSystemSubEmitterProperties properties = particleSys.subEmitters.GetSubEmitterProperties(i);
                    ParticleSystemSubEmitterType       type       = particleSys.subEmitters.GetSubEmitterType(i);
                    JSONObject res     = new JSONObject(JSONObject.Type.OBJECT);
                    int        typeNum = 0;
                    switch (type)
                    {
                    case ParticleSystemSubEmitterType.Birth:
                        typeNum = 0;
                        break;

                    case ParticleSystemSubEmitterType.Collision:
                        typeNum = 1;
                        break;

                    case ParticleSystemSubEmitterType.Death:
                        typeNum = 2;
                        break;

                    default:
                        break;
                    }
                    res.AddField("type", typeNum);
                    int propertiesNum = 0;
                    switch (properties)
                    {
                    case ParticleSystemSubEmitterProperties.InheritNothing:
                        propertiesNum = 0;
                        break;

                    case ParticleSystemSubEmitterProperties.InheritEverything:
                        propertiesNum = 1;
                        break;

                    case ParticleSystemSubEmitterProperties.InheritColor:
                        propertiesNum = 2;
                        break;

                    case ParticleSystemSubEmitterProperties.InheritSize:
                        propertiesNum = 3;
                        break;

                    case ParticleSystemSubEmitterProperties.InheritRotation:
                        propertiesNum = 4;
                        break;

                    default:
                        break;
                    }
                    res.AddField("properties", propertiesNum);

                    subEmittersData.Add(res);
                }
            }

            return(json);
        }
Example #28
0
    public void LateUpdate()
    {
        int maxParticles = _mainModule.maxParticles;

        if (_system == null || _particles.Length < maxParticles)
        {
            _particles = new ParticleSystem.Particle[maxParticles];
        }

        int lrIdx             = 0;
        int lineRendererCount = _lineRenderers.Count;

        if (lineRendererCount > MaxLineRenderers)
        {
            for (int i = MaxLineRenderers; i < lineRendererCount; i++)
            {
                Destroy(_lineRenderers[i].gameObject);
            }
            int removeCount = lineRendererCount - MaxLineRenderers;
            _lineRenderers.RemoveRange(MaxLineRenderers, removeCount);
            lineRendererCount -= removeCount;
        }

        if (MaxConnections > 0 && MaxLineRenderers > 0)
        {
            _system.GetParticles(_particles);
            int particleCount = _system.particleCount;

            float maxDistanceSqr = MaxDistance * MaxDistance;

            ParticleSystemSimulationSpace simulationSpace = _mainModule.simulationSpace;

            switch (simulationSpace)
            {
            case ParticleSystemSimulationSpace.Local:
            {
                _transform = transform;
                break;
            }

            case ParticleSystemSimulationSpace.Custom:
            {
                _transform = _mainModule.customSimulationSpace;
                break;
            }

            case ParticleSystemSimulationSpace.World:
            {
                _transform = transform;
                break;
            }

            default:
                Debug.LogError("Simulation space doesn't manage.");
                break;
            }


            for (int i = 0; i < particleCount; ++i)
            {
                if (lrIdx == MaxLineRenderers)
                {
                    break;
                }

                Vector3 p1 = _particles[i].position;

                int connections = 0;

                for (int j = i + 1; j < particleCount; ++j)
                {
                    Vector3 p2          = _particles[j].position;
                    float   distanceSqr = Vector3.Magnitude(p1 - p2);

                    if (distanceSqr <= maxDistanceSqr)
                    {
                        LineRenderer lr;

                        if (lrIdx == lineRendererCount)
                        {
                            lr = Instantiate(LineRendererTemplate, _transform, false);
                            _lineRenderers.Add(lr);

                            lineRendererCount++;
                        }

                        lr = _lineRenderers[lrIdx];

                        lr.enabled       = true;
                        lr.useWorldSpace = simulationSpace == ParticleSystemSimulationSpace.World;

                        lr.SetPosition(0, p1);
                        lr.SetPosition(1, p2);

                        lrIdx++;
                        connections++;

                        if (connections >= MaxConnections)
                        {
                            break;
                        }
                    }
                }
            }
        }

        for (int i = lrIdx; i < _lineRenderers.Count; ++i)
        {
            _lineRenderers[i].enabled = false;
        }
    }
		public ParticleData GetPositionByLife(float _normalizedLifeTime, ParticleSystemSimulationSpace _simulationSpace)
		{
			appliedNormalizedValue = _normalizedLifeTime*(pointArrayLenght);
			lowerPoint = Mathf.FloorToInt(appliedNormalizedValue);

			if (highQualityFollow) 
			{
				upperPoint = Mathf.Clamp(lowerPoint+1,0,pointArrayLenght);
				t = Mathf.InverseLerp(lowerPoint,upperPoint,appliedNormalizedValue);

				if (_simulationSpace == ParticleSystemSimulationSpace.World)
					cacheReturnPoint = Vector3.Lerp(pointArrayWorld[lowerPoint],pointArrayWorld[upperPoint], t);
				else
					cacheReturnPoint = Vector3.Lerp(pointArray[lowerPoint],pointArray[upperPoint], t);

				if (updateSpeed)
				{	
					cacheParticleData.speed = Vector3.Lerp(speedAtPoint[lowerPoint],speedAtPoint[upperPoint],t);
				}
			}
			else
			{
				if (_simulationSpace == ParticleSystemSimulationSpace.World)
					cacheReturnPoint = pointArrayWorld[lowerPoint];
				else
					cacheReturnPoint = pointArray[lowerPoint];

				if (updateSpeed)
				{
					cacheParticleData.speed = speedAtPoint[lowerPoint];
				}
			}

			cacheParticleData.position = cacheReturnPoint;

			return cacheParticleData;
		}
Example #30
0
                // ...

                void LateUpdate()
                {
                    int lineRenderersCount = lineRenderers.Count;

                    // In case max line renderers value is changed at runtime -> destroy extra.

                    if (lineRenderersCount > maxLineRenderers)
                    {
                        for (int i = maxLineRenderers; i < lineRenderersCount; i++)
                        {
                            Destroy(lineRenderers[i].gameObject);
                        }

                        lineRenderers.RemoveRange(maxLineRenderers, lineRenderersCount - maxLineRenderers);
                        lineRenderersCount -= lineRenderersCount - maxLineRenderers;
                    }

                    if (alwaysUpdate || visible)
                    {
                        // Prevent constant allocations so long as max particle count doesn't change.

                        int maxParticles = particleSystemMainModule.maxParticles;

                        if (particles == null || particles.Length < maxParticles)
                        {
                            particles = new ParticleSystem.Particle[maxParticles];

                            particlePositions = new Vector3[maxParticles];

                            particleColours = new Color[maxParticles];
                            particleSizes   = new float[maxParticles];
                        }

                        timer += Time.deltaTime;

                        if (timer >= delay)
                        {
                            timer = 0.0f;

                            int lrIndex = 0;

                            // Only update if drawing/making connections.

                            if (maxConnections > 0 && maxLineRenderers > 0)
                            {
                                particleSystem.GetParticles(particles);
                                int particleCount = particleSystem.particleCount;

                                float maxDistanceSqr = maxDistance * maxDistance;

                                ParticleSystemSimulationSpace simulationSpace = particleSystemMainModule.simulationSpace;
                                ParticleSystemScalingMode     scalingMode     = particleSystemMainModule.scalingMode;

                                Transform customSimulationSpaceTransform = particleSystemMainModule.customSimulationSpace;

                                Color lineRendererStartColour = lineRendererTemplate.startColor;
                                Color lineRendererEndColour   = lineRendererTemplate.endColor;

                                float lineRendererStartWidth = lineRendererTemplate.startWidth * lineRendererTemplate.widthMultiplier;
                                float lineRendererEndWidth   = lineRendererTemplate.endWidth * lineRendererTemplate.widthMultiplier;

                                // Save particle properties in a quick loop (accessing these is expensive and loops significantly more later, so it's better to save them once now).

                                for (int i = 0; i < particleCount; i++)
                                {
                                    particlePositions[i] = particles[i].position;

                                    particleColours[i] = particles[i].GetCurrentColor(particleSystem);
                                    particleSizes[i]   = particles[i].GetCurrentSize(particleSystem);
                                }

                                Vector3 p1p2_difference;

                                // If in world space, there's no need to do any of the extra calculations... simplify the loop!

                                if (simulationSpace == ParticleSystemSimulationSpace.World)
                                {
                                    for (int i = 0; i < particleCount; i++)
                                    {
                                        if (lrIndex == maxLineRenderers)
                                        {
                                            break;
                                        }

                                        Color particleColour = particleColours[i];

                                        Color lineStartColour = Color.LerpUnclamped(lineRendererStartColour, particleColour, colourFromParticle);
                                        lineStartColour.a = Mathf.LerpUnclamped(lineRendererStartColour.a, particleColour.a, alphaFromParticle);

                                        float lineStartWidth = Mathf.LerpUnclamped(lineRendererStartWidth, particleSizes[i], widthFromParticle);

                                        int connections = 0;

                                        for (int j = i + 1; j < particleCount; j++)
                                        {
                                            p1p2_difference.x = particlePositions[i].x - particlePositions[j].x;
                                            p1p2_difference.y = particlePositions[i].y - particlePositions[j].y;
                                            p1p2_difference.z = particlePositions[i].z - particlePositions[j].z;

                                            //float distanceSqr = Vector3.SqrMagnitude(p1p2_difference);

                                            float distanceSqr =

                                                p1p2_difference.x * p1p2_difference.x +
                                                p1p2_difference.y * p1p2_difference.y +
                                                p1p2_difference.z * p1p2_difference.z;

                                            if (distanceSqr <= maxDistanceSqr)
                                            {
                                                LineRenderer lr;

                                                if (lrIndex == lineRenderersCount)
                                                {
                                                    lr = Instantiate(lineRendererTemplate, _transform, false);

                                                    lineRenderers.Add(lr);
                                                    lineRenderersCount++;
                                                }

                                                lr = lineRenderers[lrIndex]; lr.enabled = true;

                                                lr.SetPosition(0, particlePositions[i]);
                                                lr.SetPosition(1, particlePositions[j]);

                                                lr.startColor = lineStartColour;

                                                particleColour = particleColours[j];

                                                Color lineEndColour = Color.LerpUnclamped(lineRendererEndColour, particleColour, colourFromParticle);
                                                lineEndColour.a = Mathf.LerpUnclamped(lineRendererEndColour.a, particleColour.a, alphaFromParticle);

                                                lr.endColor = lineEndColour;

                                                lr.startWidth = lineStartWidth;
                                                lr.endWidth   = Mathf.LerpUnclamped(lineRendererEndWidth, particleSizes[j], widthFromParticle);

                                                lrIndex++;
                                                connections++;

                                                if (connections == maxConnections || lrIndex == maxLineRenderers)
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                                else
                                {
                                    Vector3    position   = Vector3.zero;
                                    Quaternion rotation   = Quaternion.identity;
                                    Vector3    localScale = Vector3.one;

                                    Transform simulationSpaceTransform = _transform;

                                    switch (simulationSpace)
                                    {
                                    case ParticleSystemSimulationSpace.Local:
                                    {
                                        position   = simulationSpaceTransform.position;
                                        rotation   = simulationSpaceTransform.rotation;
                                        localScale = simulationSpaceTransform.localScale;

                                        break;
                                    }

                                    case ParticleSystemSimulationSpace.Custom:
                                    {
                                        simulationSpaceTransform = customSimulationSpaceTransform;

                                        position   = simulationSpaceTransform.position;
                                        rotation   = simulationSpaceTransform.rotation;
                                        localScale = simulationSpaceTransform.localScale;

                                        break;
                                    }

                                    default:
                                    {
                                        throw new System.NotSupportedException(

                                                  string.Format("Unsupported scaling mode '{0}'.", simulationSpace));
                                    }
                                    }

                                    // I put these here so I can take out the default exception case.
                                    // Else I'd have a compiler error for potentially unassigned variables.

                                    Vector3 p1_position = Vector3.zero;
                                    Vector3 p2_position = Vector3.zero;

                                    for (int i = 0; i < particleCount; i++)
                                    {
                                        if (lrIndex == maxLineRenderers)
                                        {
                                            break;
                                        }

                                        switch (simulationSpace)
                                        {
                                        case ParticleSystemSimulationSpace.Local:
                                        case ParticleSystemSimulationSpace.Custom:
                                        {
                                            switch (scalingMode)
                                            {
                                            case ParticleSystemScalingMode.Hierarchy:
                                            {
                                                p1_position = simulationSpaceTransform.TransformPoint(particlePositions[i]);

                                                break;
                                            }

                                            case ParticleSystemScalingMode.Local:
                                            {
                                                // Order is important.

                                                //p1_position = Vector3.Scale(particlePositions[i], localScale);

                                                p1_position.x = particlePositions[i].x * localScale.x;
                                                p1_position.y = particlePositions[i].y * localScale.y;
                                                p1_position.z = particlePositions[i].z * localScale.z;

                                                p1_position = rotation * p1_position;
                                                //p1_position += position;

                                                p1_position.x += position.x;
                                                p1_position.y += position.y;
                                                p1_position.z += position.z;

                                                break;
                                            }

                                            case ParticleSystemScalingMode.Shape:
                                            {
                                                // Order is important.

                                                p1_position = rotation * particlePositions[i];
                                                //p1_position += position;

                                                p1_position.x += position.x;
                                                p1_position.y += position.y;
                                                p1_position.z += position.z;

                                                break;
                                            }

                                            default:
                                            {
                                                throw new System.NotSupportedException(

                                                          string.Format("Unsupported scaling mode '{0}'.", scalingMode));
                                            }
                                            }

                                            break;
                                        }
                                        }

                                        Color particleColour = particleColours[i];

                                        Color lineStartColour = Color.LerpUnclamped(lineRendererStartColour, particleColour, colourFromParticle);
                                        lineStartColour.a = Mathf.LerpUnclamped(lineRendererStartColour.a, particleColour.a, alphaFromParticle);

                                        float lineStartWidth = Mathf.LerpUnclamped(lineRendererStartWidth, particleSizes[i], widthFromParticle);

                                        int connections = 0;

                                        for (int j = i + 1; j < particleCount; j++)
                                        {
                                            // Note that because particles array is not sorted by distance,
                                            // but rather by spawn time (I think), the connections made are
                                            // not necessarily the closest.

                                            switch (simulationSpace)
                                            {
                                            case ParticleSystemSimulationSpace.Local:
                                            case ParticleSystemSimulationSpace.Custom:
                                            {
                                                switch (scalingMode)
                                                {
                                                case ParticleSystemScalingMode.Hierarchy:
                                                {
                                                    p2_position = simulationSpaceTransform.TransformPoint(particlePositions[j]);

                                                    break;
                                                }

                                                case ParticleSystemScalingMode.Local:
                                                {
                                                    // Order is important.

                                                    //p2_position = Vector3.Scale(particlePositions[j], localScale);

                                                    p2_position.x = particlePositions[j].x * localScale.x;
                                                    p2_position.y = particlePositions[j].y * localScale.y;
                                                    p2_position.z = particlePositions[j].z * localScale.z;

                                                    p2_position = rotation * p2_position;
                                                    //p2_position += position;

                                                    p2_position.x += position.x;
                                                    p2_position.y += position.y;
                                                    p2_position.z += position.z;

                                                    break;
                                                }

                                                case ParticleSystemScalingMode.Shape:
                                                {
                                                    // Order is important.

                                                    p2_position = rotation * particlePositions[j];
                                                    //p2_position += position;

                                                    p2_position.x += position.x;
                                                    p2_position.y += position.y;
                                                    p2_position.z += position.z;

                                                    break;
                                                }

                                                default:
                                                {
                                                    throw new System.NotSupportedException(

                                                              string.Format("Unsupported scaling mode '{0}'.", scalingMode));
                                                }
                                                }

                                                break;
                                            }
                                            }

                                            p1p2_difference.x = particlePositions[i].x - particlePositions[j].x;
                                            p1p2_difference.y = particlePositions[i].y - particlePositions[j].y;
                                            p1p2_difference.z = particlePositions[i].z - particlePositions[j].z;

                                            // Note that distance is always calculated in WORLD SPACE.
                                            // Scaling the particle system will stretch the distances
                                            // and may require adjusting the maxDistance value.

                                            // I could also do it in local space (which may actually make more
                                            // sense) by just getting the difference of the positions without
                                            // all the transformations. This also provides opportunity for
                                            // optimization as I can limit the world space transform calculations
                                            // to only happen if a particle is within range.

                                            // Think about: Putting in a bool to switch between the two?

                                            //float distanceSqr = Vector3.SqrMagnitude(p1p2_difference);

                                            float distanceSqr =

                                                p1p2_difference.x * p1p2_difference.x +
                                                p1p2_difference.y * p1p2_difference.y +
                                                p1p2_difference.z * p1p2_difference.z;

                                            // If distance to particle within range, add new vertex position.

                                            // The larger the max distance, the quicker connections will
                                            // reach its max, terminating the loop earlier. So even though more lines have
                                            // to be drawn, it's still faster to have a larger maxDistance value because
                                            // the call to Vector3.Distance() is expensive.

                                            if (distanceSqr <= maxDistanceSqr)
                                            {
                                                LineRenderer lr;

                                                if (lrIndex == lineRenderersCount)
                                                {
                                                    lr = Instantiate(lineRendererTemplate, _transform, false);

                                                    lineRenderers.Add(lr);
                                                    lineRenderersCount++;
                                                }

                                                lr = lineRenderers[lrIndex]; lr.enabled = true;

                                                lr.SetPosition(0, p1_position);
                                                lr.SetPosition(1, p2_position);

                                                lr.startColor = lineStartColour;

                                                particleColour = particleColours[j];

                                                Color lineEndColour = Color.LerpUnclamped(lineRendererEndColour, particleColour, colourFromParticle);
                                                lineEndColour.a = Mathf.LerpUnclamped(lineRendererEndColour.a, particleColour.a, alphaFromParticle);

                                                lr.endColor = lineEndColour;

                                                lr.startWidth = lineStartWidth;
                                                lr.endWidth   = Mathf.LerpUnclamped(lineRendererEndWidth, particleSizes[j], widthFromParticle);

                                                lrIndex++;
                                                connections++;

                                                if (connections == maxConnections || lrIndex == maxLineRenderers)
                                                {
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            // Disable remaining line renderers from the pool that weren't used.

                            for (int i = lrIndex; i < lineRenderersCount; i++)
                            {
                                if (lineRenderers[i].enabled)
                                {
                                    lineRenderers[i].enabled = false;
                                }
                            }
                        }
                    }
                }
Example #31
0
        static public void Draw(LightParticleSystem2D id, Camera camera)
        {
            ParticleSystem.Particle particle;
            Vector2 size, pos;

            ParticleSystem particleSystem = id.GetParticleSystem();

            if (particleSystem == null)
            {
                return;
            }

            ParticleSystemRenderer particleSystemRenderer = id.GetParticleSystemRenderer();

            if (particleSystemRenderer == null)
            {
                return;
            }

            ParticleSystemSimulationSpace simulationSpace = particleSystem.main.simulationSpace;

            if (id.particleArray == null || id.particleArray.Length < particleSystem.main.maxParticles)
            {
                id.particleArray = new ParticleSystem.Particle[particleSystem.main.maxParticles];
            }

            int particlesAlive = particleSystem.GetParticles(id.particleArray);

            Texture texture = particleSystemRenderer.sharedMaterial.mainTexture;

            if (id.customParticle)
            {
                texture = id.customParticle;
            }

            Vector2 offset  = -camera.transform.position;
            Vector2 pOffset = offset;

            float rotation = id.transform.eulerAngles.z * Mathf.Deg2Rad;
            Color color    = id.color;

            switch (simulationSpace)
            {
            case ParticleSystemSimulationSpace.Local:
                pOffset.x += id.transform.position.x;
                pOffset.y += id.transform.position.y;
                break;
            }

            Material material = Lighting2D.materials.GetAdditive();

            material.SetColor("_TintColor", color);
            material.mainTexture = texture;

            material.SetPass(0);

            GL.Begin(GL.QUADS);

            for (int p = 0; p < particlesAlive; p++)
            {
                particle = id.particleArray [p];

                if (particle.remainingLifetime < 0.1f)
                {
                    continue;
                }

                size.x = (particle.GetCurrentSize(particleSystem) * id.scale) / 2;
                size.y = size.x;

                switch (simulationSpace)
                {
                case ParticleSystemSimulationSpace.Local:
                    pos = particle.position;

                    float angle    = Mathf.Atan2(pos.y, pos.x) + rotation;
                    float distance = pos.magnitude;

                    pos.x = Mathf.Cos(angle) * distance;
                    pos.y = Mathf.Sin(angle) * distance;

                    pos.x *= id.transform.localScale.x;
                    pos.y *= id.transform.localScale.y;

                    break;

                case ParticleSystemSimulationSpace.World:
                    pos = particle.position;
                    break;

                default:
                    pos = Vector2.zero;

                    break;
                }

                pos.x += pOffset.x;
                pos.y += pOffset.y;

                //if (InCamera(camera, pos, size.x) == false) {
                //continue;
                //}

                Particle.DrawPass(material, pos, size, particle.rotation, 0);
            }

            GL.End();
        }
		/// <summary>
		/// Starts the playback of this Playground Recorder with specified starting point, playback speed and if looping should occur.
		/// </summary>
		/// <param name="fromNormalizedTime">From normalized time in recording.</param>
		/// <param name="speed">The speed of the playback.</param>
		/// <param name="repeat">If set to <c>true</c> then enable looping.</param>
		public void Play (float fromNormalizedTime, float speed, bool repeat)
		{
			if (!_hasPlaygroundSystem)
				return;
			if (!_isReplaying && localSpaceOnPlayback)
			{
				_previousSimulationSpace = playgroundSystem.shurikenParticleSystem.simulationSpace;
				playgroundSystem.shurikenParticleSystem.simulationSpace = ParticleSystemSimulationSpace.Local;
			}

			playgroundSystem.inPlayback = true;
			playbackSpeed = speed;
			loopPlayback = repeat;
			playHead = fromNormalizedTime;
			_isReplaying = true;
			StopRecording();
			StartPlayback();

			if (playHead >= 1f)
				playHead = 0;

			if (Application.isPlaying)
				StartCoroutine(PlayRecordedFrames(playHead));
		}