Пример #1
0
        /// <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);
        }
Пример #2
0
		/// <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;
		}