forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathClassificationSystem.cs
More file actions
119 lines (112 loc) · 6.1 KB
/
Copy pathClassificationSystem.cs
File metadata and controls
119 lines (112 loc) · 6.1 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
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.NetCode;
using Unity.NetCode.LowLevel;
namespace Samples.HelloNetcode
{
[WorldSystemFilter(WorldSystemFilterFlags.ClientSimulation)]
[UpdateInGroup(typeof(GhostSimulationSystemGroup))]
[UpdateAfter(typeof(GhostSpawnClassificationSystem))]
[CreateAfter(typeof(GhostCollectionSystem))]
[CreateAfter(typeof(GhostReceiveSystem))]
[BurstCompile]
public partial struct ClassificationSystem : ISystem
{
SnapshotDataLookupHelper m_SnapshotDataLookupHelper;
BufferLookup<PredictedGhostSpawn> m_PredictedGhostSpawnLookup;
ComponentLookup<GrenadeData> m_GrenadeDataLookup;
// The ghost type (grenade) this classification system will process
int m_GhostType;
[BurstCompile]
public void OnCreate(ref SystemState state)
{
m_SnapshotDataLookupHelper = new SnapshotDataLookupHelper(ref state,
SystemAPI.GetSingletonEntity<GhostCollection>(),
SystemAPI.GetSingletonEntity<SpawnedGhostEntityMap>());
m_PredictedGhostSpawnLookup = state.GetBufferLookup<PredictedGhostSpawn>();
m_GrenadeDataLookup = state.GetComponentLookup<GrenadeData>();
state.RequireForUpdate<GhostSpawnQueue>();
state.RequireForUpdate<PredictedGhostSpawnList>();
state.RequireForUpdate<NetworkId>();
state.RequireForUpdate<GrenadeSpawner>();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
if (m_GhostType == 0)
{
// Lookup the grenade prefab entity in the ghost prefab list, from there we can find the ghost type for this prefab
var prefabEntity = SystemAPI.GetSingleton<GrenadeSpawner>().Grenade;
var collectionEntity = SystemAPI.GetSingletonEntity<GhostCollection>();
var ghostPrefabTypes = state.EntityManager.GetBuffer<GhostCollectionPrefab>(collectionEntity);
for (int i = 0; i < ghostPrefabTypes.Length; ++i)
{
if (ghostPrefabTypes[i].GhostPrefab == prefabEntity)
m_GhostType = ghostPrefabTypes[i].GhostType.GetHashCode();
}
}
m_SnapshotDataLookupHelper.Update(ref state);
m_PredictedGhostSpawnLookup.Update(ref state);
m_GrenadeDataLookup.Update(ref state);
var classificationJob = new ClassificationJob
{
snapshotDataLookupHelper = m_SnapshotDataLookupHelper,
spawnListEntity = SystemAPI.GetSingletonEntity<PredictedGhostSpawnList>(),
PredictedSpawnListLookup = m_PredictedGhostSpawnLookup,
grenadeDataLookup = m_GrenadeDataLookup,
ghostType = m_GhostType
};
state.Dependency = classificationJob.Schedule(state.Dependency);
}
[WithAll(typeof(GhostSpawnQueue))]
[BurstCompile]
partial struct ClassificationJob : IJobEntity
{
public SnapshotDataLookupHelper snapshotDataLookupHelper;
public Entity spawnListEntity;
public BufferLookup<PredictedGhostSpawn> PredictedSpawnListLookup;
public ComponentLookup<GrenadeData> grenadeDataLookup;
public int ghostType;
public void Execute(DynamicBuffer<GhostSpawnBuffer> ghosts, DynamicBuffer<SnapshotDataBuffer> data)
{
var predictedSpawnList = PredictedSpawnListLookup[spawnListEntity];
var snapshotDataLookup = snapshotDataLookupHelper.CreateSnapshotBufferLookup();
for (int i = 0; i < ghosts.Length; ++i)
{
var newGhostSpawn = ghosts[i];
if (newGhostSpawn.SpawnType != GhostSpawnBuffer.Type.Predicted || newGhostSpawn.HasClassifiedPredictedSpawn || newGhostSpawn.PredictedSpawnEntity != Entity.Null)
continue;
// Mark all the grenade spawns as classified even if not our own predicted spawns
// otherwise spawns from other players might be picked up by the default classification system when
// it runs when we happen to have a predicted spawn in the predictedSpawnList not yet classified here
if (newGhostSpawn.GhostType == ghostType)
newGhostSpawn.HasClassifiedPredictedSpawn = true;
// Find new ghost spawns (from ghost snapshot) which match the predict spawned ghost type handled by
// this classification system. Match the spawn ID data from the new spawn (by lookup it up in
// snapshot data) with the spawn IDs of ghosts in the predicted spawn list. When matched we replace
// the ghost entity of that new spawn with our predict spawned entity (so the spawn will not result
// in a new instantiation).
for (int j = 0; j < predictedSpawnList.Length; ++j)
{
if (newGhostSpawn.GhostType == predictedSpawnList[j].ghostType)
{
if (snapshotDataLookup.TryGetComponentDataFromSnapshotHistory(newGhostSpawn.GhostType, data, out GrenadeData grenadeData, i))
{
var spawnIdFromList = grenadeDataLookup[predictedSpawnList[j].entity].SpawnId;
if (grenadeData.SpawnId == spawnIdFromList)
{
newGhostSpawn.PredictedSpawnEntity = predictedSpawnList[j].entity;
predictedSpawnList[j] = predictedSpawnList[predictedSpawnList.Length - 1];
predictedSpawnList.RemoveAt(predictedSpawnList.Length - 1);
break;
}
}
}
}
ghosts[i] = newGhostSpawn;
}
}
}
}
}