forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTestEntityCreationAPI.cs
More file actions
140 lines (116 loc) · 4.53 KB
/
Copy pathTestEntityCreationAPI.cs
File metadata and controls
140 lines (116 loc) · 4.53 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
using System.Collections;
using System.Collections.Generic;
using Unity.Collections;
using Unity.Entities;
using Unity.Jobs;
using Unity.Mathematics;
using Unity.Rendering;
using Unity.Entities.Graphics;
using Unity.Transforms;
using UnityEngine;
using UnityEngine.Rendering;
public class TestEntityCreationAPI : MonoBehaviour
{
public int EntityCount = 10000;
public float ObjectScale = 0.1f;
public float Radius = 10;
public float Twists = 16;
public List<Mesh> Meshes;
public Material Material;
[GenerateTestsForBurstCompatibility]
public struct SpawnJob : IJobParallelFor
{
public Entity Prototype;
public int EntityCount;
public int MeshCount;
public float ObjectScale;
public float Radius;
public float Twists;
public EntityCommandBuffer.ParallelWriter Ecb;
[ReadOnly]
public NativeArray<RenderBounds> MeshBounds;
public void Execute(int index)
{
var e = Ecb.Instantiate(index, Prototype);
// Prototype has all correct components up front, can use SetComponent
Ecb.SetComponent(index, e, new LocalToWorld {Value = ComputeTransform(index)});
Ecb.SetComponent(index, e, new MaterialColor() {Value = ComputeColor(index)});
// MeshBounds must be set according to the actual mesh for culling to work.
int meshIndex = index % MeshCount;
Ecb.SetComponent(index, e, MaterialMeshInfo.FromRenderMeshArrayIndices(0, meshIndex));
Ecb.SetComponent(index, e, MeshBounds[meshIndex]);
}
public float4 ComputeColor(int index)
{
float t = (float) index / (EntityCount - 1);
var color = Color.HSVToRGB(t, 1, 1);
return new float4(color.r, color.g, color.b, 1);
}
public float4x4 ComputeTransform(int index)
{
float t = (float) index / (EntityCount - 1);
float h = 2 * Radius;
float r = math.sin(t * math.PI) * Radius;
float phi = t * Twists * (2 * math.PI);
float x = math.cos(phi) * r;
float z = math.sin(phi) * r;
float y = t * h - Radius;
float4x4 M = float4x4.TRS(
new float3(x, y, z),
quaternion.identity,
new float3(ObjectScale));
return M;
}
}
// Start is called before the first frame update
void Start()
{
var world = World.DefaultGameObjectInjectionWorld;
var entityManager = world.EntityManager;
EntityCommandBuffer ecbJob = new EntityCommandBuffer(Allocator.TempJob);
var filterSettings = RenderFilterSettings.Default;
filterSettings.ShadowCastingMode = ShadowCastingMode.Off;
filterSettings.ReceiveShadows = false;
var renderMeshArray = new RenderMeshArray(new[] {Material}, Meshes.ToArray());
var renderMeshDescription = new RenderMeshDescription
{
FilterSettings = filterSettings,
LightProbeUsage = LightProbeUsage.Off,
};
var prototype = entityManager.CreateEntity();
RenderMeshUtility.AddComponents(
prototype,
entityManager,
renderMeshDescription,
renderMeshArray,
MaterialMeshInfo.FromRenderMeshArrayIndices(0, 0));
entityManager.AddComponentData(prototype, new MaterialColor());
var bounds = new NativeArray<RenderBounds>(Meshes.Count, Allocator.TempJob);
for (int i = 0; i < bounds.Length; ++i)
bounds[i] = new RenderBounds {Value = Meshes[i].bounds.ToAABB()};
// Spawn most of the entities in a Burst job by cloning a pre-created prototype entity,
// which can be either a Prefab or an entity created at run time like in this sample.
// This is the fastest and most efficient way to create entities at run time.
var spawnJob = new SpawnJob
{
Prototype = prototype,
Ecb = ecbJob.AsParallelWriter(),
EntityCount = EntityCount,
MeshCount = Meshes.Count,
MeshBounds = bounds,
ObjectScale = ObjectScale,
Radius = Radius,
Twists = Twists,
};
var spawnHandle = spawnJob.Schedule(EntityCount, 128);
bounds.Dispose(spawnHandle);
spawnHandle.Complete();
ecbJob.Playback(entityManager);
ecbJob.Dispose();
entityManager.DestroyEntity(prototype);
}
// Update is called once per frame
void Update()
{
}
}