Skip to content

Commit 5fbe871

Browse files
author
davidv-unity
committed
Updated ECSSamples
1 parent 71ee202 commit 5fbe871

File tree

65 files changed

+205
-309
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

65 files changed

+205
-309
lines changed

ECSSamples/Assets/Advanced/BlobAsset/Mesh.prefab

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ MonoBehaviour:
4040
m_GameObject: {fileID: 2206451551555309766}
4141
m_Enabled: 1
4242
m_EditorHideFlags: 0
43-
m_Script: {fileID: 11500000, guid: 3aa4602fe8083734482a395b2eefdb13, type: 3}
43+
m_Script: {fileID: 11500000, guid: ada46fd23c7e67b47958492275dcf075, type: 3}
4444
m_Name:
4545
m_EditorClassIdentifier:
4646
MeshScale: 1

ECSSamples/Assets/Advanced/BlobAsset/MeshBBConversionSystem.cs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public class MeshBBConversionSystem : GameObjectConversionSystem
2525
protected override void OnCreate()
2626
{
2727
base.OnCreate();
28-
GetEntityQuery(ComponentType.ReadOnly<MeshToBoundingBoxsAuthoring>());
28+
GetEntityQuery(ComponentType.ReadOnly<MeshToBoundingBoxAuthoring>());
2929
}
3030

3131
protected override void OnUpdate()
@@ -40,7 +40,7 @@ protected override void OnUpdate()
4040
using (var context = new BlobAssetComputationContext<MeshBBFactorySettings, MeshBBBlobAsset>(BlobAssetStore, 128, Allocator.Temp))
4141
{
4242
// First step: for all changed GameObjects we compute the hash of their blob asset then get the asset or register its computation
43-
Entities.ForEach((MeshToBoundingBoxsAuthoring auth) =>
43+
Entities.ForEach((MeshToBoundingBoxAuthoring auth) =>
4444
{
4545
// Compute the blob asset hash based on Authoring properties
4646
var hasMesh = auth.Mesh != null;
@@ -49,7 +49,7 @@ protected override void OnUpdate()
4949

5050
// Query the context to determine if we need to build the BlobAsset
5151
processBlobAssets.Add(hash);
52-
context.AssociateBlobAssetWithGameObject(hash, auth.gameObject);
52+
context.AssociateBlobAssetWithUnityObject(hash, auth.gameObject);
5353
if (context.NeedToComputeBlobAsset(hash))
5454
{
5555
Profiler.BeginSample("CopyVertices");
@@ -112,14 +112,15 @@ protected override void OnUpdate()
112112

113113
// Third step, create the ECS component with the associated blob asset
114114
var index = 0;
115-
Entities.ForEach((MeshToBoundingBoxsAuthoring auth) =>
115+
Entities.ForEach((MeshToBoundingBoxAuthoring auth) =>
116116
{
117117
context.GetBlobAsset(processBlobAssets[index++], out var blob);
118118

119119
// Create the ECS component for the given GameObject
120120
var entity = GetPrimaryEntity(auth);
121121

122122
DstEntityManager.AddComponentData(entity, new MeshBBComponent(blob));
123+
DstEntityManager.AddComponentData(entity,new Translation{Value=auth.transform.position});
123124
});
124125

125126
Profiler.EndSample();

ECSSamples/Assets/Advanced/BlobAsset/MeshBBRenderSystem.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using UnityEngine;
66

77
[ExecuteAlways]
8-
[UpdateInGroup(typeof(PresentationSystemGroup))]
98
public class MeshBBRenderSystem : ComponentSystem
109
{
1110
protected override void OnUpdate()

ECSSamples/Assets/Advanced/BlobAsset/MeshToBoundingBoxsAuthoring.cs renamed to ECSSamples/Assets/Advanced/BlobAsset/MeshToBoundingBoxAuthoring.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
using UnityEngine;
33
using UnityObject = UnityEngine.Object;
44

5-
public class MeshToBoundingBoxsAuthoring : MonoBehaviour
5+
public class MeshToBoundingBoxAuthoring : MonoBehaviour
66
{
77
public float MeshScale = 1;
88
public Mesh Mesh;

ECSSamples/Assets/Advanced/BlobAsset/MeshToBoundingBoxsAuthoring.cs.meta renamed to ECSSamples/Assets/Advanced/BlobAsset/MeshToBoundingBoxAuthoring.cs.meta

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# BlobAsset Conversion Sample
2+
3+
This sample demonstrates how to convert a information from a GameObject containing a Unity Authoring component to a BlobAsset using the `BlobAssetStore` and `BlobAssetComputationContext` types.
4+
5+
## What does it show
6+
7+
The sample contains a SubScene with 512 GameObjects. Each GameObject has a "MeshToBoundingBoxAuthoring" component that defines the information we want to store in a blob asset. (The GameObjects are stored as a nested prefab to save disk space).
8+
9+
After conversion, the `MeshBBRenderSystem` uses the blob asset to draw a bounding box for each of the 512 converted entities. (The renderer uses the Unity `Debug.Draw()` function, so the bounding box only appears in the Scene view.)
10+
11+
## Sample elements:
12+
13+
* **BlobAsset Scene** — a standard Unity Scene. It contains the Subscene.
14+
* **Subscene** — contains the grid of GameObjects to convert.
15+
* **Prefabs**:
16+
* **M4** — a line made up of four Game objects.
17+
* **M16** — a square made up of four M4 lines.
18+
* **M64** — a cube made up of four M16 squares.
19+
* **M512** — a cube made up of eight M64 cubes .
20+
* **MeshToBoundingBoxsAuthoring** — defines the mesh and scale from which to compute the bounding boxes. Although each component in the sample starts out the same, you can assign different values to each component.
21+
* **MeshBBComponent** —defines the structure of the blob asset used to store the computed bounding boxes and also the IComponentData struct used to assign a BlobAssetReference to an individual entity.
22+
* **MeshBBConversionSystem** — Converts each unique combination of the values of Mesh and Scale encountered in the MeshToBoundingBoxsAuthoring components to a unique blob asset.
23+
* **MeshBBRenderSystem** — draws the bounding boxes in the Unity Scene view.
24+
25+
## What it does
26+
27+
The `MeshToBoundingBoxAuthoring` authoring component has two properties:
28+
29+
1. **Mesh**: you assign a mesh from which the bounding box is computed
30+
2. **Mesh Scale**: a scale that will be applied to the bounding box
31+
32+
The `MeshBBConversionSystem` converts this component to a BlobAsset that contains the bounding box info of the selected mesh scaled with the given value.
33+
34+
Each GameObject in the Subscene with the Authoring component is then converted to an ECS Entity that has a `MeshBBComponent` component data referencing the appropriate BlobAsset.
35+
36+
The BlobAsset is shared among entities if it has the same properties (Mesh & Mesh Scale).
37+
38+
The MeshBBRenderSystem processes all the `MeshBBComponent` instances and renders their bounding boxes in the editor using the Unity `Debug.Draw()` function . (Note that this sample does not render in the Game view or provide any runtime behavior in the Play mode.)
39+
40+
## Some insights
41+
42+
The `MeshBBConversionSystem` is a ` GameObjectConversionSystem` that does most of the interesting work in this sample. Conversion systems run in the Editor when you make a change to the relevant GameObjects and Components in a Subscene and also when you open or close a Subscene for editing.
43+
44+
`MeshBBConversionSystem` performs its conversion task in three steps:
45+
46+
1. For all changed `MeshToBoundingBoxAuthoring` authoring components, the system determines if a BlobAsset must be computed and pushes the values needed to compute the asset onto the `BlobAssetComputationContext` computation stack.
47+
2. Schedules a job to compute the blob assets using the values created in step 1.
48+
3. Creates a MeshBBComponent, assigns the corresponding `BlobAssetReference` for the blob asset created in step 2, and adds the component to the entity.
49+
50+
A `GameObjectConversionSystem` is a `ComponentSystem`, so it normally performs its work on the main thread. However, as this sample illustrates, you can use the C# Job System to move some parts of a conversion to worker threads. The `BlobAssetComputationContext` provides the `AddBlobAssetToCompute()` function to help optimize blob asset creation.
51+
52+
Using the `AddBlobAssetToCompute()` function, you can add a *settings* struct containing the values you need in order to create the blob asset to the *context*, associating a set of values with a hash. The hash value is used to determine whether a given authoring component represents a new blob asset or if it should share one already added for a different authoring component. You also use the hash to retrieve a reference to the blob asset after it is created.
53+

ECSSamples/Assets/Advanced/BlobAsset/README.md.meta

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ECSSamples/Assets/Advanced/Boids/Scripts/BoidSchool.cs

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public struct BoidSchool : IComponentData
1616
public int Count;
1717
}
1818

19-
public class BoidSchoolSpawnSystem : JobComponentSystem
19+
public class BoidSchoolSpawnSystem : SystemBase
2020
{
2121
[BurstCompile]
2222
struct SetBoidLocalToWorld : IJobParallelFor
@@ -43,7 +43,7 @@ public void Execute(int i)
4343
}
4444
}
4545

46-
protected override JobHandle OnUpdate(JobHandle inputDeps)
46+
protected override void OnUpdate()
4747
{
4848
Entities.WithStructuralChanges().ForEach((Entity entity, int entityInQueryIndex, in BoidSchool boidSchool, in LocalToWorld boidSchoolLocalToWorld) =>
4949
{
@@ -61,13 +61,11 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
6161
Center = boidSchoolLocalToWorld.Position,
6262
Radius = boidSchool.InitialRadius
6363
};
64-
inputDeps = setBoidLocalToWorldJob.Schedule(boidSchool.Count, 64, inputDeps);
65-
inputDeps = boidEntities.Dispose(inputDeps);
64+
Dependency = setBoidLocalToWorldJob.Schedule(boidSchool.Count, 64, Dependency);
65+
Dependency = boidEntities.Dispose(Dependency);
6666

6767
EntityManager.DestroyEntity(entity);
6868
}).Run();
69-
70-
return inputDeps;
7169
}
7270
}
7371
}

ECSSamples/Assets/Advanced/Boids/Scripts/BoidSystem.cs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace Samples.Boids
1919
{
2020
[UpdateInGroup(typeof(SimulationSystemGroup))]
2121
[UpdateBefore(typeof(TransformSystemGroup))]
22-
public class BoidSystem : JobComponentSystem
22+
public class BoidSystem : SystemBase
2323
{
2424
EntityQuery m_BoidQuery;
2525
EntityQuery m_TargetQuery;
@@ -101,7 +101,7 @@ public void ExecuteNext(int cellIndex, int index)
101101
}
102102
}
103103

104-
protected override JobHandle OnUpdate(JobHandle inputDeps)
104+
protected override void OnUpdate()
105105
{
106106
var obstacleCount = m_ObstacleQuery.CalculateEntityCount();
107107
var targetCount = m_TargetQuery.CalculateEntityCount();
@@ -157,7 +157,7 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
157157
{
158158
cellAlignment[entityInQueryIndex] = localToWorld.Forward;
159159
})
160-
.Schedule(inputDeps);
160+
.ScheduleParallel(Dependency);
161161

162162
var initialCellSeparationJobHandle = Entities
163163
.WithSharedComponentFilter(settings)
@@ -166,7 +166,7 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
166166
{
167167
cellSeparation[entityInQueryIndex] = localToWorld.Position;
168168
})
169-
.Schedule(inputDeps);
169+
.ScheduleParallel(Dependency);
170170

171171
var copyTargetPositionsJobHandle = Entities
172172
.WithName("CopyTargetPositionsJob")
@@ -176,7 +176,7 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
176176
{
177177
copyTargetPositions[entityInQueryIndex] = localToWorld.Position;
178178
})
179-
.Schedule(inputDeps);
179+
.ScheduleParallel(Dependency);
180180

181181
var copyObstaclePositionsJobHandle = Entities
182182
.WithName("CopyObstaclePositionsJob")
@@ -186,7 +186,7 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
186186
{
187187
copyObstaclePositions[entityInQueryIndex] = localToWorld.Position;
188188
})
189-
.Schedule(inputDeps);
189+
.ScheduleParallel(Dependency);
190190

191191
// Populates a hash map, where each bucket contains the indices of all Boids whose positions quantize
192192
// to the same value for a given cell radius so that the information can be randomly accessed by
@@ -203,14 +203,14 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
203203
var hash = (int)math.hash(new int3(math.floor(localToWorld.Position / settings.CellRadius)));
204204
parallelHashMap.Add(hash, entityInQueryIndex);
205205
})
206-
.Schedule(inputDeps);
206+
.ScheduleParallel(Dependency);
207207

208208
var initialCellCountJob = new MemsetNativeArray<int>
209209
{
210210
Source = cellCount,
211211
Value = 1
212212
};
213-
var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, inputDeps);
213+
var initialCellCountJobHandle = initialCellCountJob.Schedule(boidCount, 64, Dependency);
214214

215215
var initialCellBarrierJobHandle = JobHandle.CombineDependencies(initialCellAlignmentJobHandle, initialCellSeparationJobHandle, initialCellCountJobHandle);
216216
var copyTargetObstacleBarrierJobHandle = JobHandle.CombineDependencies(copyTargetPositionsJobHandle, copyObstaclePositionsJobHandle);
@@ -228,7 +228,7 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
228228
targetPositions = copyTargetPositions,
229229
obstaclePositions = copyObstaclePositions
230230
};
231-
var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap,64,mergeCellsBarrierJobHandle);
231+
var mergeCellsJobHandle = mergeCellsJob.Schedule(hashMap, 64, mergeCellsBarrierJobHandle);
232232

233233
// This reads the previously calculated boid information for all the boids of each cell to update
234234
// the `localToWorld` of each of the boids based on their newly calculated headings using
@@ -307,33 +307,31 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
307307
quaternion.LookRotationSafe(nextHeading, math.up()),
308308
new float3(1.0f, 1.0f, 1.0f))
309309
};
310-
}).Schedule(mergeCellsJobHandle);
310+
}).ScheduleParallel(mergeCellsJobHandle);
311311

312312
// Dispose allocated containers with dispose jobs.
313-
inputDeps = steerJobHandle;
314-
var disposeJobHandle = hashMap.Dispose(inputDeps);
315-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellIndices.Dispose(inputDeps));
316-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellObstaclePositionIndex.Dispose(inputDeps));
317-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellTargetPositionIndex.Dispose(inputDeps));
318-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellCount.Dispose(inputDeps));
319-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellObstacleDistance.Dispose(inputDeps));
320-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellAlignment.Dispose(inputDeps));
321-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellSeparation.Dispose(inputDeps));
322-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, copyObstaclePositions.Dispose(inputDeps));
323-
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, copyTargetPositions.Dispose(inputDeps));
324-
inputDeps = disposeJobHandle;
313+
Dependency = steerJobHandle;
314+
var disposeJobHandle = hashMap.Dispose(Dependency);
315+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellIndices.Dispose(Dependency));
316+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellObstaclePositionIndex.Dispose(Dependency));
317+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellTargetPositionIndex.Dispose(Dependency));
318+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellCount.Dispose(Dependency));
319+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellObstacleDistance.Dispose(Dependency));
320+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellAlignment.Dispose(Dependency));
321+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, cellSeparation.Dispose(Dependency));
322+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, copyObstaclePositions.Dispose(Dependency));
323+
disposeJobHandle = JobHandle.CombineDependencies( disposeJobHandle, copyTargetPositions.Dispose(Dependency));
324+
Dependency = disposeJobHandle;
325325

326326
// We pass the job handle and add the dependency so that we keep the proper ordering between the jobs
327327
// as the looping iterates. For our purposes of execution, this ordering isn't necessary; however, without
328328
// the add dependency call here, the safety system will throw an error, because we're accessing multiple
329329
// pieces of boid data and it would think there could possibly be a race condition.
330330

331-
m_BoidQuery.AddDependency(inputDeps);
331+
m_BoidQuery.AddDependency(Dependency);
332332
m_BoidQuery.ResetFilter();
333333
}
334334
m_UniqueTypes.Clear();
335-
336-
return inputDeps;
337335
}
338336

339337
protected override void OnCreate()

ECSSamples/Assets/Advanced/Boids/Scripts/SampledAnimationClipPlaybackSystem.cs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66

77
namespace Samples.Boids
88
{
9-
public class SampledAnimationClipPlaybackSystem : JobComponentSystem
9+
public class SampledAnimationClipPlaybackSystem : SystemBase
1010
{
11-
protected override JobHandle OnUpdate(JobHandle inputDeps)
11+
protected override void OnUpdate()
1212
{
1313
var deltaTime = math.min(0.05f,Time.DeltaTime);
1414

15-
var transformJobHandle = Entities.ForEach((ref Translation translation, ref Rotation rotation, in SampledAnimationClip sampledAnimationClip) =>
15+
Entities.ForEach((ref Translation translation, ref Rotation rotation, in SampledAnimationClip sampledAnimationClip) =>
1616
{
1717
var frameIndex = sampledAnimationClip.FrameIndex;
1818
var timeOffset = sampledAnimationClip.TimeOffset;
@@ -25,9 +25,9 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
2525

2626
translation.Value = math.lerp(prevTranslation, nextTranslation, timeOffset);
2727
rotation.Value = math.slerp(prevRotation, nextRotation, timeOffset);
28-
}).Schedule(inputDeps);
28+
}).ScheduleParallel();
2929

30-
var clipJobHandle = Entities.ForEach((ref SampledAnimationClip sampledAnimationClip) =>
30+
Entities.ForEach((ref SampledAnimationClip sampledAnimationClip) =>
3131
{
3232
var currentTime = sampledAnimationClip.CurrentTime + deltaTime;
3333
var sampleRate = sampledAnimationClip.SampleRate;
@@ -48,9 +48,7 @@ protected override JobHandle OnUpdate(JobHandle inputDeps)
4848
sampledAnimationClip.CurrentTime = currentTime;
4949
sampledAnimationClip.FrameIndex = frameIndex;
5050
sampledAnimationClip.TimeOffset = timeOffset;
51-
}).Schedule(transformJobHandle);
52-
53-
return clipJobHandle;
51+
}).ScheduleParallel();
5452
}
5553
}
5654
}

0 commit comments

Comments
 (0)