public static void InitEmitterConeSource(EntityManager mgr, Entity emitter, NativeArray <Entity> particles, bool attachToEmitter)
        {
            var    source = mgr.GetComponentData <EmitterConeSource>(emitter);
            float3 localPositionOnConeBase;

            quaternion rotation = quaternion.identity;

            if (!attachToEmitter)
            {
                if (mgr.HasComponent <LocalToWorld>(emitter))
                {
                    var toWorld = mgr.GetComponentData <LocalToWorld>(emitter);
                    rotation = new quaternion(toWorld.Value);
                }
            }

            foreach (var particle in particles)
            {
                float angle            = m_rand.NextFloat((float)-math.PI, (float)math.PI);
                float radiusNormalized = math.sqrt(m_rand.NextFloat(0.0f, 1.0f));
                float radius           = source.radius * radiusNormalized;

                localPositionOnConeBase.x = math.sin(angle);
                localPositionOnConeBase.z = math.cos(angle);
                localPositionOnConeBase.y = 0.0f;

                var worldPositionOnConeBase = math.rotate(rotation, localPositionOnConeBase);
                var Translation             = mgr.GetComponentData <Translation>(particle);
                Translation.Value += worldPositionOnConeBase * radius;
                mgr.SetComponentData(particle, Translation);

                ParticleVelocity particleVelocity = new ParticleVelocity();
                float            spreadAngle      = source.angle * radiusNormalized;

                float directionRadius = math.sin(spreadAngle);
                float directionHeight = math.cos(spreadAngle);
                particleVelocity.velocity.x = localPositionOnConeBase.x * directionRadius;
                particleVelocity.velocity.z = localPositionOnConeBase.z * directionRadius;
                particleVelocity.velocity.y = directionHeight;
                particleVelocity.velocity  *= source.speed;

                particleVelocity.velocity = math.rotate(rotation, particleVelocity.velocity);

                if (mgr.HasComponent <ParticleVelocity>(particle))
                {
                    mgr.SetComponentData(particle, particleVelocity);
                }
                else
                {
                    mgr.AddComponentData(particle, particleVelocity);
                }
            }
        }
        public static void InitEmitterCircleSource(EntityManager mgr, Entity emitter, NativeArray <Entity> particles)
        {
            var source = mgr.GetComponentData <EmitterCircleSource>(emitter);

            foreach (var particle in particles)
            {
                float randomAngle      = m_rand.NextFloat((float)-math.PI, (float)math.PI);
                float radiusNormalized =
                    source.radius.end != 0.0f
                        ? math.sqrt(m_rand.NextFloat(source.radius.start / source.radius.end, 1.0f))
                        : 0.0f;
                float randomRadius = radiusNormalized * source.radius.end;

                var positionNormalized = new float2(math.sin(randomAngle), math.cos(randomAngle));
                var position           = new float3(positionNormalized.x * randomRadius, positionNormalized.y * randomRadius, 0.0f);
                var Translation        = mgr.GetComponentData <Translation>(particle);
                Translation.Value += position;
                mgr.SetComponentData(particle, Translation);

                if (source.speed.start != 0.0f && source.speed.end != 0.0f)
                {
                    float randomSpeed = m_rand.NextFloat(source.speed.start, source.speed.end);
                    if (source.speedBasedOnRadius)
                    {
                        randomSpeed *= radiusNormalized;
                    }

                    var particleVelocity = new ParticleVelocity()
                    {
                        velocity = new float3(positionNormalized.x * randomSpeed, positionNormalized.y * randomSpeed, 0.0f)
                    };

                    if (mgr.HasComponent <ParticleVelocity>(particle))
                    {
                        mgr.SetComponentData(particle, particleVelocity);
                    }
                    else
                    {
                        mgr.AddComponentData(particle, particleVelocity);
                    }
                }
            }
        }
示例#3
0
        private void SpawnParticles(EntityManager mgr, float deltaTime, Entity emitter)
        {
            var particleEmitter         = mgr.GetComponentData <ParticleEmitter>(emitter);
            var particleEmitterInternal = mgr.GetComponentData <ParticleEmitterInternal>(emitter);

            uint particlesToSpawn = 0;

            if (mgr.HasComponent <BurstEmissionInternal>(emitter) && mgr.HasComponent <BurstEmission>(emitter))
            {
                // Burst emission mode.
                var burstEmission         = mgr.GetComponentData <BurstEmission>(emitter);
                var burstEmissionInternal = mgr.GetComponentData <BurstEmissionInternal>(emitter);

                if (burstEmissionInternal.cycle < burstEmission.cycles)
                {
                    burstEmissionInternal.cooldown -= deltaTime;
                    if (burstEmissionInternal.cooldown < 0.0f)
                    {
                        particlesToSpawn = (uint)m_rand.NextInt((int)burstEmission.count.start, (int)burstEmission.count.end);
                        burstEmissionInternal.cycle++;
                        burstEmissionInternal.cooldown = m_rand.NextFloat(burstEmission.interval.start, burstEmission.interval.end);
                    }

                    mgr.SetComponentData(emitter, burstEmissionInternal);
                }
            }
            else
            {
                // Normal emission mode.
                if (particleEmitter.emitRate > 0.0f)
                {
                    particleEmitterInternal.particleSpawnCooldown += deltaTime;
                    float particleSpawnDelay = 1.0f / particleEmitter.emitRate;

                    particlesToSpawn = (uint)(particleEmitterInternal.particleSpawnCooldown / particleSpawnDelay);

                    if (particlesToSpawn > 0)
                    {
                        particleEmitterInternal.particleSpawnCooldown -= particleSpawnDelay * particlesToSpawn;
                        uint maxParticlesToSpawn = particleEmitter.maxParticles - particleEmitterInternal.numParticles;
                        if (particlesToSpawn > maxParticlesToSpawn)
                        {
                            particlesToSpawn = maxParticlesToSpawn;
                        }
                    }

                    mgr.SetComponentData(emitter, particleEmitterInternal);
                }
            }

            if (particlesToSpawn == 0)
            {
                return;
            }

            var newParticles = new NativeArray <Entity>((int)particlesToSpawn, Collections.Allocator.Persistent);

            // Before the new particles will spawn, Disabled component needs to be removed from the template particle.
            mgr.RemoveComponent <Disabled>(particleEmitterInternal.particleTemplate);
            mgr.Instantiate(particleEmitterInternal.particleTemplate, newParticles);
            mgr.AddComponentData(particleEmitterInternal.particleTemplate, new Disabled());

            InitTime(mgr, deltaTime, particleEmitter.lifetime, newParticles);

            if (particleEmitter.attachToEmitter)
            {
                foreach (var particle in newParticles)
                {
                    var node = new Parent()
                    {
                        Value = emitter
                    };
                    if (mgr.HasComponent <Parent>(particle))
                    {
                        mgr.SetComponentData(particle, node);
                    }
                    else
                    {
                        mgr.AddComponentData(particle, node);
                    }

                    var position = mgr.GetComponentData <Translation>(particle);
                    position.Value = float3.zero;
                    mgr.SetComponentData(particle, position);
                }
            }
            else
            {
                if (mgr.HasComponent <LocalToWorld>(emitter))
                {
                    var toWorld         = mgr.GetComponentData <LocalToWorld>(emitter);
                    var emitterWorldPos = new float3(toWorld.Value[3][0], toWorld.Value[3][1], toWorld.Value[3][2]);

                    foreach (var particle in newParticles)
                    {
                        var localPos = mgr.GetComponentData <Translation>(particle);
                        localPos.Value = emitterWorldPos;
                        mgr.SetComponentData(particle, localPos);
                    }
                }
            }

            if (mgr.HasComponent <EmitterInitialVelocity>(emitter))
            {
                var velocity         = mgr.GetComponentData <EmitterInitialVelocity>(emitter).velocity;
                var particleVelocity = new ParticleVelocity();
                foreach (var particle in newParticles)
                {
                    particleVelocity.velocity = velocity;
                    mgr.AddComponentData(particle, particleVelocity);
                }
            }
            else if (mgr.HasComponent <LifetimeVelocity>(emitter))
            {
                foreach (var particle in newParticles)
                {
                    mgr.AddComponentData(particle, new ParticleVelocity()
                    {
                        velocity = float3.zero
                    });
                }
            }

            InitScale(mgr, emitter, newParticles);
            InitColor(mgr, emitter, newParticles);
            InitRotation(mgr, emitter, newParticles);

            // Init particle's position and the velocity based on the source.
            if (mgr.HasComponent <EmitterBoxSource>(emitter))
            {
                ParticlesSource.InitEmitterBoxSource(mgr, emitter, newParticles);
            }
            else if (mgr.HasComponent <EmitterCircleSource>(emitter))
            {
                ParticlesSource.InitEmitterCircleSource(mgr, emitter, newParticles);
            }
            else if (mgr.HasComponent <EmitterConeSource>(emitter))
            {
                ParticlesSource.InitEmitterConeSource(mgr, emitter, newParticles, particleEmitter.attachToEmitter);
            }

            newParticles.Dispose();
        }