/
EnterBoostPad.cs
98 lines (85 loc) · 4.28 KB
/
EnterBoostPad.cs
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
using Unity.Burst;
using Unity.Collections;
using Unity.Collections.LowLevel.Unsafe;
using Unity.Entities;
using Unity.Physics;
using Unity.Physics.Systems;
using Unity.Tiny.Audio;
namespace TinyRacing.Systems
{
/// <summary>
/// Detect when a car with the SpeedMultiplier component is near a BoostPad to give
/// it a temporary speed boost.
/// </summary>
[UpdateInGroup(typeof(SimulationSystemGroup))]
public class EnterBoostPad : SystemBase
{
private BuildPhysicsWorld _buildPhysicsWorldSystem;
private EndSimulationEntityCommandBufferSystem _entityCommandBufferSystem;
private StepPhysicsWorld _stepPhysicsWorldSystem;
protected override void OnCreate()
{
_buildPhysicsWorldSystem = World.GetOrCreateSystem<BuildPhysicsWorld>();
_stepPhysicsWorldSystem = World.GetOrCreateSystem<StepPhysicsWorld>();
_entityCommandBufferSystem = World.GetOrCreateSystem<EndSimulationEntityCommandBufferSystem>();
}
protected override void OnUpdate()
{
Dependency = new EnterBoostPadJob
{
BoostPadGroup = GetComponentDataFromEntity<BoostPad>(true),
AudioSourceGroup = GetComponentDataFromEntity<AudioSource>(true),
PlayerGroup = GetComponentDataFromEntity<Player>(true),
SpeedMultiplierGroup = GetComponentDataFromEntity<SpeedMultiplier>(),
EntityCommandBuffer = _entityCommandBufferSystem.CreateCommandBuffer()
}.Schedule(_stepPhysicsWorldSystem.Simulation, ref _buildPhysicsWorldSystem.PhysicsWorld, Dependency);
_entityCommandBufferSystem.AddJobHandleForProducer(Dependency);
}
[BurstCompile]
private struct EnterBoostPadJob : ITriggerEventsJob
{
[ReadOnly] public ComponentDataFromEntity<BoostPad> BoostPadGroup;
[ReadOnly] public ComponentDataFromEntity<Player> PlayerGroup;
public EntityCommandBuffer EntityCommandBuffer;
[ReadOnly] public ComponentDataFromEntity<AudioSource> AudioSourceGroup;
// Because multiple worker threads can write to this, the safety system won't normally allow this job to schedule.
// We guarantee they will never write to the same
// entity key, we disable safety restrictions which would normally not allow this
[NativeDisableContainerSafetyRestriction]
public ComponentDataFromEntity<SpeedMultiplier> SpeedMultiplierGroup;
public Entity GetEntityFromComponentGroup<T>(Entity entityA, Entity entityB,
ComponentDataFromEntity<T> componentGroup) where T : struct, IComponentData
{
if (componentGroup.HasComponent(entityA))
{
return entityA;
}
if (componentGroup.HasComponent(entityB))
{
return entityB;
}
return Entity.Null;
}
public void Execute(TriggerEvent collisionEvent)
{
var entityA = collisionEvent.EntityA;
var entityB = collisionEvent.EntityB;
var boostPadEntity = GetEntityFromComponentGroup(entityA, entityB, BoostPadGroup);
var speedMultiplierEntity = GetEntityFromComponentGroup(entityA, entityB, SpeedMultiplierGroup);
if (boostPadEntity != Entity.Null && speedMultiplierEntity != Entity.Null)
{
var boostPadComponent = BoostPadGroup[boostPadEntity];
var speedMultiplierComponent = SpeedMultiplierGroup[speedMultiplierEntity];
speedMultiplierComponent.RemainingTime = boostPadComponent.SpeedBoostDuration;
speedMultiplierComponent.Multiplier = boostPadComponent.SpeedMultiplier;
SpeedMultiplierGroup[speedMultiplierEntity] = speedMultiplierComponent;
var isPlaying = AudioSourceGroup[boostPadEntity].isPlaying;
if (PlayerGroup.HasComponent(speedMultiplierEntity) && !isPlaying)
{
EntityCommandBuffer.AddComponent<AudioSourceStart>(boostPadEntity);
}
}
}
}
}
}