forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCreateTileGridSystem.cs
More file actions
136 lines (116 loc) · 5.57 KB
/
Copy pathCreateTileGridSystem.cs
File metadata and controls
136 lines (116 loc) · 5.57 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
// The purpose of this code is to build a grid of tiles (from prefabs). Each tile has a TileTriggerCounter component.
// The Sphere GameObject can be moved along the grid. Walls prevent the Sphere from rolling off the grid. Trigger events
// are recorded in the TileTriggerCounter component when the Sphere collides with a tile. Reactions to the trigger events
// are handled in the SpawnColliderFromTriggerSystem.
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.Transforms;
namespace Unity.Physics
{
[RequireMatchingQueriesForUpdate]
[UpdateInGroup(typeof(InitializationSystemGroup))]
internal partial struct CreateTileGridSystem : ISystem
{
private EntityQuery wallQuery;
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<CreateTileGridSpawnerComponent>();
}
public void OnUpdate(ref SystemState state)
{
var ecb = new EntityCommandBuffer(Allocator.Temp);
var entityManager = state.World.EntityManager;
foreach (var(creator, creatorEntity) in
SystemAPI.Query<RefRW<CreateTileGridSpawnerComponent>>()
.WithEntityAccess())
{
var initialTransform = entityManager.GetComponentData<LocalTransform>(creator.ValueRO.GridEntity);
int gridSize = 14; // Create 14x14 grid
var positions = ComputeGridPositions(gridSize, creator.ValueRO.SpawningPosition);
var spawnedEntities = new NativeArray<Entity>(gridSize * gridSize, Allocator.Temp);
ecb.Instantiate(creator.ValueRO.GridEntity, spawnedEntities);
var i = 0;
foreach (var s in spawnedEntities)
{
ecb.SetComponent(s, new LocalTransform
{
Position = positions[i],
Scale = initialTransform.Scale,
Rotation = initialTransform.Rotation
});
i++;
}
// Instantiate the Walls entity. Note that this prefab contains child entities, therefore we cannot
// update the position this pass. Will need a separate pass to do this
var wallPrefabInstance = ecb.Instantiate(creator.ValueRO.WallEntity);
ecb.SetComponent(wallPrefabInstance, new LocalTransform
{
Position = creator.ValueRO.SpawningPosition,
Scale = initialTransform.Scale,
Rotation = initialTransform.Rotation
});
ecb.AddComponent(wallPrefabInstance, new WallsTagComponent()); // Tag the wall so the entity is easy to find next pass
spawnedEntities.Dispose();
positions.Dispose();
}
ecb.Playback(entityManager);
ecb.Dispose();
// Perform a second pass to update the position of the Walls entity. Need to use the output from the first
// ECB playback here.
wallQuery = entityManager.CreateEntityQuery(new EntityQueryDesc
{
All = new[]
{
ComponentType.ReadOnly<WallsTagComponent>()
},
});
var wallArray = wallQuery.ToEntityArray(Allocator.Temp);
foreach (var wall in wallArray)
{
if (entityManager.HasBuffer<LinkedEntityGroup>(wall))
{
var leg = entityManager.GetBuffer<LinkedEntityGroup>(wall);
if (leg.Length > 1)
{
for (var j = 1; j < leg.Length; j++)
{
var childEntity = leg[j].Value;
var childPosition = entityManager.GetComponentData<LocalTransform>(childEntity);
var wallPosition = entityManager.GetComponentData<LocalTransform>(wall);
entityManager.SetComponentData(childEntity, new LocalTransform
{
Position = wallPosition.Position + childPosition.Position + new float3(0, 1.5f, 0),
Scale = childPosition.Scale,
Rotation = childPosition.Rotation
});
}
}
}
}
wallArray.Dispose();
entityManager.DestroyEntity(SystemAPI.QueryBuilder().WithAll<CreateTileGridSpawnerComponent>().Build());
}
public void OnDestroy(ref SystemState state)
{
}
// Create a grid of tiles. The startingPoint marks the middle of the grid
internal static NativeList<float3> ComputeGridPositions(int gridSize, float3 startingPosition)
{
var arrayPositions = new NativeList<float3>(gridSize * gridSize, Allocator.Temp);
int gridRadius = 1;
var startingOffset = startingPosition -
new float3(0.5f * gridSize * gridRadius, 0, 0.5f * gridSize * gridRadius) + 0.5f;
for (int i = 0; i < gridSize; ++i)
{
for (int j = 0; j < gridSize; ++j)
{
arrayPositions.Add(startingOffset + new float3(
i * gridRadius, 0, j * gridRadius));
if (arrayPositions.Length >= gridSize * gridSize) break;
}
}
return arrayPositions;
}
}
}