public bool Update() { _elapsedTime += Time.DeltaTime; // fading block if (_elapsedTime > _fadeDelay && _elapsedTime < _fadeDuration + _fadeDelay) { var t = Mathf.Map01(_elapsedTime, 0f, _fadeDelay + _fadeDuration); ColorExt.Lerp(ref _initialColor, ref _targetColor, out _renderColor, t); } else if (_elapsedTime >= _fadeDuration + _fadeDelay) { return(true); } return(false); }
/// <summary> /// updates the particle. Returns true when the particle is no longer alive /// </summary> /// <param name="emitterConfig">Emitter config.</param> public bool Update(ParticleEmitterConfig emitterConfig, ref ParticleCollisionConfig collisionConfig, Vector2 rootPosition) { // PART 1: reduce the life span of the particle _timeToLive -= Time.DeltaTime; // if the current particle is alive then update it if (_timeToLive > 0) { // only update the particle position if it has not collided. If it has, physics takes over if (!_collided) { // if maxRadius is greater than 0 then the particles are going to spin otherwise they are affected by speed and gravity if (emitterConfig.EmitterType == ParticleEmitterType.Radial) { // PART 2: update the angle of the particle from the radius. This is only done if the particles are rotating _angle += _degreesPerSecond * Time.DeltaTime; _radius += _radiusDelta * Time.DeltaTime; Vector2 tmp; tmp.X = -Mathf.Cos(_angle) * _radius; tmp.Y = -Mathf.Sin(_angle) * _radius; _velocity = tmp - position; position = tmp; } else { Vector2 tmp, radial, tangential; radial = Vector2.Zero; if (position.X != 0 || position.Y != 0) { Vector2.Normalize(ref position, out radial); } tangential = radial; radial = radial * _radialAcceleration; var newy = tangential.X; tangential.X = -tangential.Y; tangential.Y = newy; tangential = tangential * _tangentialAcceleration; tmp = radial + tangential + emitterConfig.Gravity; tmp = tmp * Time.DeltaTime; _direction = _direction + tmp; tmp = _direction * Time.DeltaTime; _velocity = tmp / Time.DeltaTime; position = position + tmp; } } // update the particles color. we do the lerp from finish-to-start because timeToLive counts from particleLifespan to 0 var t = (_particleLifetime - _timeToLive) / _particleLifetime; ColorExt.Lerp(ref _startColor, ref _finishColor, out color, t); // update the particle size particleSize += _particleSizeDelta * Time.DeltaTime; particleSize = MathHelper.Max(0, particleSize); // update the rotation of the particle rotation += _rotationDelta * Time.DeltaTime; if (collisionConfig.Enabled) { // if we already collided we have to handle the collision response if (_collided) { // handle after collision movement. we need to track velocity for this _velocity += collisionConfig.Gravity * Time.DeltaTime; position += _velocity * Time.DeltaTime; // if we move too slow we die if (_velocity.LengthSquared() < collisionConfig.MinKillSpeedSquared) { return(true); } } // should we use our spawnPosition as a reference or the parent Transforms position? var pos = emitterConfig.SimulateInWorldSpace ? spawnPosition : rootPosition; _circleCollisionShape.RecalculateBounds(particleSize * 0.5f * collisionConfig.RadiusScale, pos + position); var neighbors = Physics.BoxcastBroadphase(ref _circleCollisionShape.bounds, collisionConfig.CollidesWithLayers); foreach (var neighbor in neighbors) { CollisionResult result; if (_circleCollisionShape.CollidesWithShape(neighbor.Shape, out result)) { // handle the overlap position -= result.MinimumTranslationVector; CalculateCollisionResponseVelocity(collisionConfig.Friction, collisionConfig.Elasticity, ref result.MinimumTranslationVector); // handle collision config props _timeToLive -= _timeToLive * collisionConfig.LifetimeLoss; _collided = true; } } } } else { // timeToLive expired. were done return(true); } return(false); }