예제 #1
0
        public void UpdateOrientation(Spline spline)
        {
            if (target == null)
            {
                return;
            }

            //clamp percentage:
            if (!spline.loop)
            {
                percentage = Mathf.Clamp01(percentage);
            }

            //look in direction of spline?
            if (faceDirection)
            {
                if (spline.direction == SplineDirection.Forward)
                {
                    target.LookAt(target.position + spline.GetDirection(percentage));
                }
                else
                {
                    target.LookAt(target.position - spline.GetDirection(percentage));
                }
            }

            target.position = spline.GetPosition(percentage);
        }
    void LateUpdate()
    {
        if (_particles == null)
        {
            _particles = new ParticleSystem.Particle[_particleSystem.main.maxParticles];
        }

        int aliveParticlesCount = _particleSystem.GetParticles(_particles);

        for (int i = 0; i < aliveParticlesCount; i++)
        {
            //get calculation pieces:
            float seedMax          = Mathf.Pow(10, _particles[i].randomSeed.ToString().Length);
            float seedAsPercent    = _particles[i].randomSeed / seedMax;
            float travelPercentage = 1 - (_particles [i].remainingLifetime / _particles [i].startLifetime);

            //bypass issue while running at edit time when particles haven't reached the spline end:
            if (_spline.GetDirection(travelPercentage) == Vector3.zero)
            {
                continue;
            }

            //get a direction off our current point on the path - rotating by 1080 results in better distribution since Unity's randomSeed for particles favors lower numbers:
            Vector3 offshootDirection         = Quaternion.AngleAxis(1080 * seedAsPercent, -_spline.GetDirection(travelPercentage)) * _spline.Up(travelPercentage);
            Vector3 previousOffshootDirection = Quaternion.AngleAxis(1080 * seedAsPercent, -_spline.GetDirection(travelPercentage - _prviousDiff)) * _spline.Up(travelPercentage - _prviousDiff);

            //cache our positions:
            Vector3 position = _spline.GetPosition(travelPercentage);

            //cache a previous position for velocity if possible:
            Vector3 lastPosition = position;
            if (travelPercentage - .01f >= 0)
            {
                lastPosition = _spline.GetPosition(travelPercentage - _prviousDiff);
            }

            //decide how far to offshoot from the spline based on where we are between the start and end radius:
            float offset         = Mathf.Lerp(startRadius, endRadius, travelPercentage);
            float previousOffset = Mathf.Lerp(startRadius, endRadius, travelPercentage - _prviousDiff);

            //place particles depending on simulation space:
            Vector3 currentPosition  = Vector3.zero;
            Vector3 previousPosition = Vector3.zero;

            switch (_particleSystem.main.simulationSpace)
            {
            case ParticleSystemSimulationSpace.Local:

                currentPosition  = _particleSystem.transform.InverseTransformPoint(position + offshootDirection * offset);
                previousPosition = _particleSystem.transform.InverseTransformPoint(lastPosition + previousOffshootDirection * previousOffset);
                break;

            case ParticleSystemSimulationSpace.World:
            case ParticleSystemSimulationSpace.Custom:
                currentPosition  = position + offshootDirection * offset;
                previousPosition = position + previousOffshootDirection * previousOffset;
                break;
            }

            //apply:
            _particles [i].position = currentPosition;
            _particles [i].velocity = currentPosition - previousPosition;
        }

        //apply the particle changes back to the system:
        _particleSystem.SetParticles(_particles, _particles.Length);
    }