forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathParticleEmitterSystem.cs
More file actions
141 lines (125 loc) · 6.43 KB
/
Copy pathParticleEmitterSystem.cs
File metadata and controls
141 lines (125 loc) · 6.43 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
using Random = UnityEngine.Random;
using Unity.NetCode;
using Unity.Rendering;
using Unity.Burst;
namespace Asteroids.Client
{
[WorldSystemFilter(WorldSystemFilterFlags.Presentation)]
[UpdateBefore(typeof(ParticleUpdateSystemGroup))]
[BurstCompile]
public partial struct ParticleEmitterSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
var builder = new EntityQueryBuilder(Allocator.Temp)
.WithAll<ParticleEmitterComponentData>()
.WithNone<Particle>();
state.RequireForUpdate(state.GetEntityQuery(builder));
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var job = new EmitParticleJob
{
commandBuffer = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>().CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter(),
deltaTime = SystemAPI.Time.DeltaTime
};
state.Dependency = job.ScheduleParallel(state.Dependency);
}
[WithNone(typeof(Particle))]
[BurstCompile]
partial struct EmitParticleJob : IJobEntity
{
public EntityCommandBuffer.ParallelWriter commandBuffer;
public float deltaTime;
public void Execute(Entity entity, [EntityIndexInChunk] int entityIndexInChunk, in ParticleEmitterComponentData emitter, in LocalTransform transform)
{
if (emitter.active == 0)
return;
int particles = (int) (deltaTime * emitter.particlesPerSecond + 0.5f);
if (particles == 0)
return;
float2 spawnOffset =
math.mul(transform.Rotation, new float3(emitter.spawnOffset, 0)).xy;
bool colorTrans = math.any(emitter.startColor != emitter.endColor);
bool sizeTrans = emitter.startLength != emitter.endLength ||
emitter.startWidth != emitter.endWidth;
// Create the first particle, then instantiate the rest based on its value
var particle = commandBuffer.Instantiate(entityIndexInChunk, emitter.particlePrefab);
commandBuffer.AddComponent(entityIndexInChunk, particle, default(Particle));
commandBuffer.AddComponent(entityIndexInChunk, particle, new URPMaterialPropertyBaseColor {Value = emitter.startColor});
commandBuffer.AddComponent(entityIndexInChunk, particle, new ParticleAge(emitter.particleLifetime));
commandBuffer.AddComponent(entityIndexInChunk, particle, emitter);
// Set initial data
commandBuffer.AddComponent(entityIndexInChunk, particle, new ParticleVelocity());
commandBuffer.SetComponent(entityIndexInChunk, particle,
LocalTransform.FromPositionRotation(transform.Position + new float3(spawnOffset, 0), transform.Rotation));
commandBuffer.SetComponent(entityIndexInChunk, particle, new PostTransformMatrix {Value = float4x4.Scale(emitter.startWidth, emitter.startWidth + emitter.startLength, emitter.startWidth)});
if (colorTrans)
commandBuffer.AddComponent(entityIndexInChunk, particle,
new ParticleColorTransition(emitter.startColor,
emitter.endColor));
if (sizeTrans)
commandBuffer.AddComponent(entityIndexInChunk, particle,
new ParticleSizeTransition(emitter.startLength,
emitter.endLength, emitter.startWidth,
emitter.endWidth));
if (particles > 1)
{
for (int i = 1; i < particles; ++i)
commandBuffer.Instantiate(entityIndexInChunk, particle);
}
}
}
}
[WorldSystemFilter(WorldSystemFilterFlags.Presentation)]
[UpdateBefore(typeof(ParticleUpdateSystemGroup))]
[UpdateAfter(typeof(ParticleEmitterSystem))]
[BurstCompile]
public partial struct ParticleInitializeSystem : ISystem
{
[BurstCompile]
public void OnCreate(ref SystemState state)
{
var builder = new EntityQueryBuilder(Allocator.Temp).WithAll<Particle, ParticleEmitterComponentData>();
state.RequireForUpdate(state.GetEntityQuery(builder));
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
var job = new InitializeParticleJob
{
commandBuffer = SystemAPI.GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>().CreateCommandBuffer(state.WorldUnmanaged).AsParallelWriter(),
rand = new Unity.Mathematics.Random((uint)NetworkTimeSystem.TimestampMS)
};
state.Dependency = job.ScheduleParallel(state.Dependency);
}
[WithAll(typeof(Particle))]
[BurstCompile]
partial struct InitializeParticleJob : IJobEntity
{
public EntityCommandBuffer.ParallelWriter commandBuffer;
public Unity.Mathematics.Random rand;
public void Execute(Entity entity, [EntityIndexInChunk] int entityIndexInChunk,
ref LocalTransform transform, ref ParticleVelocity velocity,
in ParticleEmitterComponentData emitter)
{
var curRand = new Unity.Mathematics.Random(rand.NextUInt() + (uint)entityIndexInChunk);
transform.Rotation = math.mul(transform.Rotation, quaternion.RotateZ(math.radians(curRand.NextFloat(-emitter.angleSpread,
emitter.angleSpread))));
float particleVelocity = emitter.velocityBase +
curRand.NextFloat(0, emitter.velocityRandom);
float3 particleDir = new float3(0, particleVelocity, 0);
velocity.velocity += math.mul(transform.Rotation, particleDir).xy;
transform.Position.x += curRand.NextFloat(-emitter.spawnSpread, emitter.spawnSpread);
transform.Position.y += curRand.NextFloat(-emitter.spawnSpread, emitter.spawnSpread);
commandBuffer.RemoveComponent<ParticleEmitterComponentData>(entityIndexInChunk, entity);
}
}
}
}