Ejemplo n.º 1
0
        /// <summary>
        /// Calculates the effect from Manipulator's properties.
        /// </summary>
        /// <param name="playgroundParticles">Playground particles.</param>
        /// <param name="thisManipulator">This manipulator.</param>
        /// <param name="thisManipulatorProperty">This manipulator property.</param>
        /// <param name="p">Particle index.</param>
        /// <param name="t">Delta time.</param>
        /// <param name="particlePosition">Particle position.</param>
        /// <param name="manipulatorPosition">Manipulator position.</param>
        /// <param name="localSpace">Is calculation in local space?</param>
        /// <param name="contains">Does the Manipulator contain the particle at index?</param>
        public static void PropertyManipulator(PlaygroundParticlesC playgroundParticles, ManipulatorObjectC thisManipulator, ManipulatorPropertyC thisManipulatorProperty, int p, float t, Vector3 particlePosition, Vector3 manipulatorPosition, float manipulatorDistance, bool localSpace, bool contains)
        {
            if (contains) {
                switch (thisManipulatorProperty.type) {

                    // Math Property
                    case MANIPULATORPROPERTYTYPEC.Math:
                    if (thisManipulatorProperty.mathProperty.type == MATHMANIPULATORTYPE.Sin || thisManipulatorProperty.mathProperty.type == MATHMANIPULATORTYPE.Cos)
                        t = playgroundParticles.localTime;
                    switch (thisManipulatorProperty.mathProperty.property) {
                        case MATHMANIPULATORPROPERTY.Position:
                            playgroundParticles.playgroundCache.position[p] = thisManipulatorProperty.mathProperty.EvaluatePosition(playgroundParticles.playgroundCache.position[p], t);
                        break;
                        case MATHMANIPULATORPROPERTY.Velocity:
                            playgroundParticles.playgroundCache.velocity[p] = thisManipulatorProperty.mathProperty.Evaluate(playgroundParticles.playgroundCache.velocity[p], t);
                        break;
                        case MATHMANIPULATORPROPERTY.Rotation:
                            if (!playgroundParticles.rotateTowardsDirection)
                                playgroundParticles.playgroundCache.rotation[p] = thisManipulatorProperty.mathProperty.Evaluate(playgroundParticles.playgroundCache.rotation[p], t)%360f;
                        break;
                        case MATHMANIPULATORPROPERTY.Size:
                            playgroundParticles.playgroundCache.size[p] = thisManipulatorProperty.mathProperty.Evaluate(playgroundParticles.playgroundCache.size[p], t);
                            playgroundParticles.playgroundCache.changedByPropertySize[p] = true;
                        break;
                    }
                    break;

                    // Velocity Property
                    case MANIPULATORPROPERTYTYPEC.Velocity:
                    if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None)
                        playgroundParticles.playgroundCache.velocity[p] = thisManipulatorProperty.useLocalRotation?
                            thisManipulatorProperty.localVelocity
                            :
                            thisManipulatorProperty.velocity;
                    else {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], thisManipulatorProperty.useLocalRotation?
                            thisManipulatorProperty.localVelocity
                            :
                        thisManipulatorProperty.velocity, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                    }
                    break;

                    // Additive Velocity Property
                    case MANIPULATORPROPERTYTYPEC.AdditiveVelocity:
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.velocity[p] += thisManipulatorProperty.useLocalRotation?
                            thisManipulatorProperty.localVelocity*((t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing)
                            :
                            thisManipulatorProperty.velocity*((t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                    break;

                    // Color Property
                    case MANIPULATORPROPERTYTYPEC.Color:
                    Color staticColor;
                    if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                        if (thisManipulatorProperty.keepColorAlphas) {
                            staticColor = thisManipulatorProperty.color;
                            staticColor.a = Mathf.Clamp(playgroundParticles.lifetimeColor.Evaluate(playgroundParticles.playgroundCache.life[p]/playgroundParticles.lifetime).a, 0, staticColor.a);
                            playgroundParticles.particleCache[p].color = staticColor;
                        } else playgroundParticles.particleCache[p].color = thisManipulatorProperty.color;
                    } else {
                        if (thisManipulatorProperty.keepColorAlphas) {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            staticColor = thisManipulatorProperty.color;
                            staticColor.a = Mathf.Clamp(playgroundParticles.lifetimeColor.Evaluate(playgroundParticles.playgroundCache.life[p]/playgroundParticles.lifetime).a, 0, staticColor.a);
                            playgroundParticles.particleCache[p].color = Color.Lerp(playgroundParticles.particleCache[p].color, staticColor, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                        } else playgroundParticles.particleCache[p].color = Color.Lerp(playgroundParticles.particleCache[p].color, thisManipulatorProperty.color, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                        playgroundParticles.playgroundCache.changedByPropertyColorLerp[p] = true;
                    }

                    // Only color in range of manipulator boundaries
                    playgroundParticles.playgroundCache.changedByPropertyColor[p] = true;

                    // Keep alpha of original color
                    if (thisManipulatorProperty.keepColorAlphas)
                        playgroundParticles.playgroundCache.changedByPropertyColorKeepAlpha[p] = true;

                    // Set color pairing key
                    if (playgroundParticles.playgroundCache.propertyColorId[p] != thisManipulator.manipulatorId) {
                        playgroundParticles.playgroundCache.propertyColorId[p] = thisManipulator.manipulatorId;
                    }
                    break;

                    // Lifetime Color Property
                    case MANIPULATORPROPERTYTYPEC.LifetimeColor:
                    if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                        playgroundParticles.particleCache[p].color = thisManipulatorProperty.lifetimeColor.Evaluate(playgroundParticles.lifetime>0?playgroundParticles.playgroundCache.life[p]/playgroundParticles.lifetime:0);
                    } else {
                        playgroundParticles.particleCache[p].color = Color.Lerp(playgroundParticles.particleCache[p].color, thisManipulatorProperty.lifetimeColor.Evaluate(playgroundParticles.lifetime>0?playgroundParticles.playgroundCache.life[p]/playgroundParticles.lifetime:0), (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                        playgroundParticles.playgroundCache.changedByPropertyColorLerp[p] = true;
                    }

                    // Only color in range of manipulator boundaries
                    playgroundParticles.playgroundCache.changedByPropertyColor[p] = true;

                    // Set color pairing key
                    if (playgroundParticles.playgroundCache.propertyColorId[p] != thisManipulator.manipulatorId) {
                        playgroundParticles.playgroundCache.propertyColorId[p] = thisManipulator.manipulatorId;
                    }
                    break;

                    // Size Property
                    case MANIPULATORPROPERTYTYPEC.Size:
                    if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0f?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:0;
                        if (manipulatorDistance==0)
                            playgroundParticles.playgroundCache.size[p] = thisManipulatorProperty.size;
                        else
                            playgroundParticles.playgroundCache.size[p] = thisManipulatorProperty.size+(thisManipulatorProperty.size/(1f+(manipulatorDistance/thisManipulator.strengthSmoothing))*(thisManipulator.strength*thisManipulatorProperty.strength));
                    } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.size[p] = Mathf.Lerp(playgroundParticles.playgroundCache.size[p], thisManipulatorProperty.size, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                    } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.size[p] = Mathf.MoveTowards(playgroundParticles.playgroundCache.size[p], thisManipulatorProperty.size, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                    }

                    playgroundParticles.playgroundCache.changedByPropertySize[p] = true;
                    break;

                    // Target Property
                    case MANIPULATORPROPERTYTYPEC.Target:
                    if (thisManipulatorProperty.targets.Count>0 && thisManipulatorProperty.targets[thisManipulatorProperty.targetPointer].available) {

                        // Set target pointer
                        if (playgroundParticles.playgroundCache.propertyId[p] != thisManipulator.manipulatorId) {

                            playgroundParticles.playgroundCache.propertyTarget[p] = thisManipulatorProperty.targetPointer;
                            thisManipulatorProperty.targetPointer++; thisManipulatorProperty.targetPointer=thisManipulatorProperty.targetPointer%thisManipulatorProperty.targets.Count;
                            playgroundParticles.playgroundCache.propertyId[p] = thisManipulator.manipulatorId;
                        }

                        // Teleport or lerp to position based on transition type
                        if (playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId && thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].available) {
                            if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None)
                                playgroundParticles.playgroundCache.position[p] = localSpace?
                                    thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].localPosition
                                :
                                    thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].position;
                            else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                                manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                playgroundParticles.playgroundCache.position[p] = localSpace?
                                        Vector3.Lerp(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].localPosition, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing)
                                :
                                            Vector3.Lerp(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].position, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                if (thisManipulatorProperty.zeroVelocityStrength>0)
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                            } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                                manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                playgroundParticles.playgroundCache.position[p] = localSpace?
                                        Vector3.MoveTowards(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].localPosition, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing)
                                :
                                            Vector3.MoveTowards(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].position, (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                if (thisManipulatorProperty.zeroVelocityStrength>0)
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                            }

                            // This particle was changed by a target property
                            playgroundParticles.playgroundCache.changedByPropertyTarget[p] = true;
                        }
                    }
                    break;

                    // Death Property
                    case MANIPULATORPROPERTYTYPEC.Death:
                    if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None)
                        playgroundParticles.playgroundCache.life[p] = playgroundParticles.lifetime;
                    else {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.birth[p] -= (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing;
                    }

                    // This particle was changed by a death property
                    playgroundParticles.playgroundCache.changedByPropertyDeath[p] = true;
                    break;

                    // Attractors
                    case MANIPULATORPROPERTYTYPEC.Attractor:
                    if (!playgroundParticles.onlySourcePositioning) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.Distance (manipulatorPosition, playgroundParticles.playgroundCache.position[p])/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], (manipulatorPosition-particlePosition)*((thisManipulatorProperty.strength*thisManipulator.strength)/manipulatorDistance), t*((thisManipulatorProperty.strength*thisManipulator.strength)/manipulatorDistance)/thisManipulator.strengthSmoothing);
                    }
                    break;

                    // Attractors Gravitational
                    case MANIPULATORPROPERTYTYPEC.Gravitational:
                    if (!playgroundParticles.onlySourcePositioning) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.Distance (manipulatorPosition, playgroundParticles.playgroundCache.position[p])/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], (manipulatorPosition-particlePosition)*(thisManipulatorProperty.strength*thisManipulator.strength)/manipulatorDistance, t/thisManipulator.strengthSmoothing);
                    }
                    break;

                    // Repellents
                    case MANIPULATORPROPERTYTYPEC.Repellent:
                    if (!playgroundParticles.onlySourcePositioning) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.Distance (manipulatorPosition, playgroundParticles.playgroundCache.position[p])/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], (particlePosition-manipulatorPosition)*((thisManipulatorProperty.strength*thisManipulator.strength)/manipulatorDistance), t*((thisManipulatorProperty.strength*thisManipulator.strength)/manipulatorDistance)/thisManipulator.strengthSmoothing);
                    }
                    break;

                    // Vortex
                    case MANIPULATORPROPERTYTYPEC.Vortex:
                    if (!playgroundParticles.onlySourcePositioning) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.Distance (manipulatorPosition, playgroundParticles.playgroundCache.position[p])/thisManipulator.strengthDistanceEffect:10f;
                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], ((manipulatorPosition-particlePosition)*(thisManipulator.strength*thisManipulatorProperty.strength)/manipulatorDistance)-Vector3.Cross(thisManipulator.transform.up, (manipulatorPosition-particlePosition))*(thisManipulator.strength*thisManipulatorProperty.strength)/manipulatorDistance, (t*(thisManipulator.strength*thisManipulatorProperty.strength)/manipulatorDistance)/thisManipulator.strengthSmoothing);
                    }
                    break;

                    // Turbulence
                    case MANIPULATORPROPERTYTYPEC.Turbulence:
                    if (!playgroundParticles.onlySourcePositioning && thisManipulatorProperty.turbulenceType!=TURBULENCETYPE.None) {
                        manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.Distance (manipulatorPosition, particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                        Turbulence (
                            playgroundParticles,
                            thisManipulatorProperty.turbulenceSimplex,
                            p,
                            t/thisManipulator.strengthSmoothing,
                            thisManipulatorProperty.turbulenceType,
                            thisManipulatorProperty.turbulenceTimeScale,
                            thisManipulatorProperty.turbulenceScale,
                            ((thisManipulatorProperty.strength*thisManipulator.strength)/manipulatorDistance),
                            thisManipulatorProperty.turbulenceApplyLifetimeStrength,
                            thisManipulatorProperty.turbulenceLifetimeStrength
                        );
                    }
                    break;

                    // Mesh Target
                    case MANIPULATORPROPERTYTYPEC.MeshTarget:
                    if (!playgroundParticles.onlySourcePositioning && thisManipulatorProperty.meshTarget.initialized) {

                        // Set target pointer
                        if (playgroundParticles.playgroundCache.propertyId[p] != thisManipulator.manipulatorId) {
                            playgroundParticles.playgroundCache.propertyTarget[p] = thisManipulatorProperty.targetSortingList[thisManipulatorProperty.targetPointer];
                            thisManipulatorProperty.targetPointer++; thisManipulatorProperty.targetPointer=thisManipulatorProperty.targetPointer%thisManipulatorProperty.meshTarget.vertexPositions.Length;
                            playgroundParticles.playgroundCache.propertyId[p] = thisManipulator.manipulatorId;
                        }

                        // Teleport or lerp to position based on transition type
                        if (playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId) {
                            if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                                playgroundParticles.playgroundCache.position[p] = thisManipulatorProperty.meshTargetMatrix.MultiplyPoint3x4(thisManipulatorProperty.meshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.meshTarget.vertexPositions.Length]);
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.zero;
                            } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                                    playgroundParticles.playgroundCache.position[p] = Vector3.Lerp(particlePosition, thisManipulatorProperty.meshTargetMatrix.MultiplyPoint3x4(thisManipulatorProperty.meshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.meshTarget.vertexPositions.Length]), (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                if (thisManipulatorProperty.zeroVelocityStrength>0)
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                            } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                                    playgroundParticles.playgroundCache.position[p] = Vector3.MoveTowards(particlePosition, thisManipulatorProperty.meshTargetMatrix.MultiplyPoint3x4(thisManipulatorProperty.meshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.meshTarget.vertexPositions.Length]), (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                if (thisManipulatorProperty.zeroVelocityStrength>0)
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                            }

                            // This particle was changed by a target property
                            playgroundParticles.playgroundCache.changedByPropertyTarget[p] = true;
                        }

                    }
                    break;

                    // Skinned Mesh Target
                    case MANIPULATORPROPERTYTYPEC.SkinnedMeshTarget:
                    if (!playgroundParticles.onlySourcePositioning && thisManipulatorProperty.skinnedMeshTarget.initialized) {

                        // Set target pointer
                        if (playgroundParticles.playgroundCache.propertyId[p] != thisManipulator.manipulatorId) {
                            playgroundParticles.playgroundCache.propertyTarget[p] = thisManipulatorProperty.targetSortingList[thisManipulatorProperty.targetPointer];
                            thisManipulatorProperty.targetPointer++; thisManipulatorProperty.targetPointer=thisManipulatorProperty.targetPointer%thisManipulatorProperty.skinnedMeshTarget.vertexPositions.Length;
                            playgroundParticles.playgroundCache.propertyId[p] = thisManipulator.manipulatorId;
                        }

                        // Teleport or lerp to position based on transition type
                        if (playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId) {
                            if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                                playgroundParticles.playgroundCache.position[p] = thisManipulatorProperty.skinnedMeshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.skinnedMeshTarget.vertexPositions.Length];
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.zero;
                            } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                                manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                playgroundParticles.playgroundCache.position[p] = Vector3.Lerp(particlePosition, thisManipulatorProperty.skinnedMeshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.skinnedMeshTarget.vertexPositions.Length], t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                if (thisManipulatorProperty.zeroVelocityStrength>0)
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                            } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                                manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                playgroundParticles.playgroundCache.position[p] = Vector3.MoveTowards(particlePosition, thisManipulatorProperty.skinnedMeshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.skinnedMeshTarget.vertexPositions.Length], t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                if (thisManipulatorProperty.zeroVelocityStrength>0)
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                            }

                            // This particle was changed by a target property
                            playgroundParticles.playgroundCache.changedByPropertyTarget[p] = true;
                        }
                    }
                    break;

                    // State Target
                    case MANIPULATORPROPERTYTYPEC.StateTarget:
                    if (!playgroundParticles.onlySourcePositioning && thisManipulatorProperty.stateTarget.initialized && !thisManipulatorProperty.stateTarget.IsInitializing()) {

                        // Set target pointer
                        if (playgroundParticles.playgroundCache.propertyId[p] != thisManipulator.manipulatorId) {
                            playgroundParticles.playgroundCache.propertyTarget[p] = thisManipulatorProperty.targetSortingList[thisManipulatorProperty.targetPointer%thisManipulatorProperty.targetSortingList.Length];
                            thisManipulatorProperty.targetPointer++; thisManipulatorProperty.targetPointer=thisManipulatorProperty.targetPointer%thisManipulatorProperty.stateTarget.positionLength;
                            playgroundParticles.playgroundCache.propertyId[p] = thisManipulator.manipulatorId;
                        }

                        // Teleport or lerp to position based on transition type
                        if (playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId) {
                            Vector3 newPos = thisManipulatorProperty.stateTarget.stateTransformMx.MultiplyPoint3x4(thisManipulatorProperty.stateTarget.GetPosition(playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.stateTarget.positionLength));
                            if (!thisManipulatorProperty.onlyPositionInRange || thisManipulatorProperty.onlyPositionInRange && thisManipulator.Contains (newPos, manipulatorPosition)) {
                                if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                                    playgroundParticles.playgroundCache.position[p] = newPos;
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.zero;
                                } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                                    manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                    playgroundParticles.playgroundCache.position[p] = Vector3.Lerp(particlePosition, newPos, t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                    if (thisManipulatorProperty.zeroVelocityStrength>0)
                                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                                } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                                    manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                    playgroundParticles.playgroundCache.position[p] = Vector3.MoveTowards(particlePosition, newPos, t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                    if (thisManipulatorProperty.zeroVelocityStrength>0)
                                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                                }

                                // This particle was changed by a target property
                                playgroundParticles.playgroundCache.changedByPropertyTarget[p] = true;
                            }

                        }

                    }
                    break;

                    // Spline Target
                    case MANIPULATORPROPERTYTYPEC.SplineTarget:
                    if (!playgroundParticles.onlySourcePositioning && thisManipulatorProperty.SplineTargetIsReady()) {

                        // Set target pointer
                        if (playgroundParticles.playgroundCache.propertyId[p] != thisManipulator.manipulatorId) {
                            playgroundParticles.playgroundCache.propertyId[p] = thisManipulator.manipulatorId;
                        }

                        // Teleport or lerp to position based on transition type
                        if (playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId) {
                            Vector3 newPos = thisManipulatorProperty.splineTarget.GetPoint(thisManipulatorProperty.splineTargetMethod==SPLINETARGETMETHOD.SplineTime? ((p*1f)/(playgroundParticles.particleCount*1f))+thisManipulatorProperty.splineTimeOffset : ((playgroundParticles.playgroundCache.life[p]+playgroundParticles.playgroundCache.lifetimeSubtraction[p])/playgroundParticles.lifetime)+thisManipulatorProperty.splineTimeOffset);
                            if (!thisManipulatorProperty.onlyPositionInRange || thisManipulatorProperty.onlyPositionInRange && thisManipulator.Contains (newPos, manipulatorPosition)) {
                                if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                                    playgroundParticles.playgroundCache.position[p] = newPos;
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.zero;
                                } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                                    manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                    playgroundParticles.playgroundCache.position[p] = Vector3.Lerp(particlePosition, newPos, t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                    if (thisManipulatorProperty.zeroVelocityStrength>0)
                                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                                } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                                    manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                                    playgroundParticles.playgroundCache.position[p] = Vector3.MoveTowards(particlePosition, newPos, t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                                    if (thisManipulatorProperty.zeroVelocityStrength>0)
                                        playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                                }

                                // This particle was changed by a target property
                                playgroundParticles.playgroundCache.changedByPropertyTarget[p] = true;
                            }

                        }

                    }
                    break;
                }

                playgroundParticles.playgroundCache.changedByProperty[p] = true;

            } else {

                // Handle size outside
                if (thisManipulatorProperty.onlySizeInRange)
                    playgroundParticles.playgroundCache.changedByPropertySize[p] = false;

                // Handle colors outside of property manipulator range
                if (playgroundParticles.playgroundCache.propertyColorId[p] == thisManipulator.manipulatorId && (thisManipulatorProperty.type == MANIPULATORPROPERTYTYPEC.Color || thisManipulatorProperty.type == MANIPULATORPROPERTYTYPEC.LifetimeColor)) {

                    // Lerp back color with previous set key
                    if (playgroundParticles.playgroundCache.changedByPropertyColorLerp[p] && thisManipulatorProperty.transition != MANIPULATORPROPERTYTRANSITIONC.None && thisManipulatorProperty.onlyColorInRange) {
                        playgroundParticles.particleCache[p].color = Color.Lerp(playgroundParticles.particleCache[p].color, playgroundParticles.lifetimeColor.Evaluate(playgroundParticles.playgroundCache.life[p]/playgroundParticles.lifetime), t*thisManipulatorProperty.strength*thisManipulator.strength);
                    }

                    if (thisManipulatorProperty.type == MANIPULATORPROPERTYTYPEC.LifetimeColor && !thisManipulatorProperty.onlyColorInRange) {
                        if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.None) {
                            playgroundParticles.particleCache[p].color = thisManipulatorProperty.lifetimeColor.Evaluate(playgroundParticles.lifetime>0?playgroundParticles.playgroundCache.life[p]/playgroundParticles.lifetime:0);
                        } else {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            playgroundParticles.particleCache[p].color = Color.Lerp(playgroundParticles.particleCache[p].color, thisManipulatorProperty.lifetimeColor.Evaluate(playgroundParticles.lifetime>0?playgroundParticles.playgroundCache.life[p]/playgroundParticles.lifetime:0), (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                        }
                    }

                    if (thisManipulatorProperty.onlyColorInRange)
                        playgroundParticles.playgroundCache.changedByPropertyColor[p] = false;
                }

                // Position onto targets when outside of range
                if (!playgroundParticles.onlySourcePositioning && !thisManipulatorProperty.onlyPositionInRange && thisManipulatorProperty.transition != MANIPULATORPROPERTYTRANSITIONC.None) {

                    // Target (Transform) positioning outside of range
                    if (thisManipulatorProperty.type == MANIPULATORPROPERTYTYPEC.Target) {
                        if (thisManipulatorProperty.targets.Count>0 && thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count]!=null) {
                            if (playgroundParticles.playgroundCache.changedByPropertyTarget[p] && thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].available && playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.transform.GetInstanceID()) {
                                if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp)
                                    playgroundParticles.playgroundCache.position[p] = localSpace?
                                        Vector3.Lerp(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].localPosition, t*(thisManipulatorProperty.strength*thisManipulator.strength)/thisManipulator.strengthSmoothing)
                                        :
                                        Vector3.Lerp(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].position, t*(thisManipulatorProperty.strength*thisManipulator.strength)/thisManipulator.strengthSmoothing);
                                else
                                    playgroundParticles.playgroundCache.position[p] = localSpace?
                                        Vector3.MoveTowards(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].localPosition, t*(thisManipulatorProperty.strength*thisManipulator.strength)/thisManipulator.strengthSmoothing)
                                        :
                                        Vector3.MoveTowards(particlePosition, thisManipulatorProperty.targets[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.targets.Count].position, t*(thisManipulatorProperty.strength*thisManipulator.strength)/thisManipulator.strengthSmoothing);

                                if (thisManipulatorProperty.zeroVelocityStrength>0)
                                    playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                            }
                        }
                    }

                    // Mesh Target positioning outside of range
                    if (thisManipulatorProperty.type == MANIPULATORPROPERTYTYPEC.MeshTarget && thisManipulatorProperty.meshTarget.initialized && playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId) {
                        if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            playgroundParticles.playgroundCache.position[p] = Vector3.Lerp(particlePosition, thisManipulatorProperty.meshTargetMatrix.MultiplyPoint3x4(thisManipulatorProperty.meshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.meshTarget.vertexPositions.Length]), (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                            if (thisManipulatorProperty.zeroVelocityStrength>0)
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                        } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            playgroundParticles.playgroundCache.position[p] = Vector3.MoveTowards(particlePosition, thisManipulatorProperty.meshTargetMatrix.MultiplyPoint3x4(thisManipulatorProperty.meshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.meshTarget.vertexPositions.Length]), (t*thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                            if (thisManipulatorProperty.zeroVelocityStrength>0)
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                        }
                    }

                    // Skinned Mesh Target positioning outside of range
                    if (thisManipulatorProperty.type == MANIPULATORPROPERTYTYPEC.SkinnedMeshTarget && thisManipulatorProperty.skinnedMeshTarget.initialized && playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId) {
                        if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            playgroundParticles.playgroundCache.position[p] = Vector3.Lerp(particlePosition, thisManipulatorProperty.skinnedMeshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.skinnedMeshTarget.vertexPositions.Length], t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                            if (thisManipulatorProperty.zeroVelocityStrength>0)
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                        } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            playgroundParticles.playgroundCache.position[p] = Vector3.MoveTowards(particlePosition, thisManipulatorProperty.skinnedMeshTarget.vertexPositions[playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.skinnedMeshTarget.vertexPositions.Length], t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                            if (thisManipulatorProperty.zeroVelocityStrength>0)
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                        }
                    }

                    // State Target positioning outside of range
                    if (thisManipulatorProperty.type == MANIPULATORPROPERTYTYPEC.StateTarget && thisManipulatorProperty.stateTarget.initialized && !thisManipulatorProperty.stateTarget.IsInitializing() && playgroundParticles.playgroundCache.propertyId[p] == thisManipulator.manipulatorId) {
                        if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Lerp) {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            playgroundParticles.playgroundCache.position[p] = Vector3.Lerp(particlePosition, thisManipulatorProperty.stateTarget.stateTransformMx.MultiplyPoint3x4(thisManipulatorProperty.stateTarget.GetPosition(playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.stateTarget.positionLength)), t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                            if (thisManipulatorProperty.zeroVelocityStrength>0)
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                        } else if (thisManipulatorProperty.transition == MANIPULATORPROPERTYTRANSITIONC.Linear) {
                            manipulatorDistance = thisManipulator.strengthDistanceEffect>0?Vector3.SqrMagnitude (manipulatorPosition - particlePosition)/thisManipulator.strengthDistanceEffect:10f;
                            playgroundParticles.playgroundCache.position[p] = Vector3.MoveTowards(particlePosition, thisManipulatorProperty.stateTarget.stateTransformMx.MultiplyPoint3x4(thisManipulatorProperty.stateTarget.GetPosition(playgroundParticles.playgroundCache.propertyTarget[p]%thisManipulatorProperty.stateTarget.positionLength)), t*(thisManipulatorProperty.strength*thisManipulator.strength/manipulatorDistance)/thisManipulator.strengthSmoothing);
                            if (thisManipulatorProperty.zeroVelocityStrength>0)
                                playgroundParticles.playgroundCache.velocity[p] = Vector3.Lerp(playgroundParticles.playgroundCache.velocity[p], Vector3.zero, t*thisManipulatorProperty.zeroVelocityStrength);
                        }
                    }
                }
            }
        }