-
Notifications
You must be signed in to change notification settings - Fork 91
/
MegaCityThinInputSystem.cs
85 lines (70 loc) · 3.41 KB
/
MegaCityThinInputSystem.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
using System.Diagnostics;
using Unity.Burst;
using Unity.Collections;
using Unity.Entities;
using Unity.Mathematics;
using Unity.NetCode;
namespace Unity.Megacity.Gameplay
{
/// <summary>
/// System to handle input for the thin client
/// </summary>
[UpdateInGroup(typeof(GhostInputSystemGroup))]
[WorldSystemFilter(WorldSystemFilterFlags.ThinClientSimulation)]
public partial struct MegacityThinInputSystem : ISystem
{
private NativeReference<Random> m_Rand;
public void OnCreate(ref SystemState state)
{
state.RequireForUpdate<NetworkId>();
state.RequireForUpdate<NetworkStreamInGame>();
state.RequireForUpdate<NetworkTime>();
m_Rand = new NativeReference<Random>(Allocator.Persistent, NativeArrayOptions.UninitializedMemory);
m_Rand.Value = Random.CreateFromIndex((uint) Stopwatch.GetTimestamp());
}
[BurstCompile]
public void OnDestroy(ref SystemState state)
{
m_Rand.Dispose();
}
[BurstCompile]
public void OnUpdate(ref SystemState state)
{
if (!SystemAPI.TryGetSingletonRW<CommandTarget>(out var commandTargetRw))
return;
// Ensure AI has input entity:
if (commandTargetRw.ValueRO.targetEntity == Entity.Null || !state.EntityManager.HasComponent<PlayerVehicleInput>(commandTargetRw.ValueRO.targetEntity))
{
var inputEntity = state.EntityManager.CreateEntity();
commandTargetRw.ValueRW.targetEntity = inputEntity;
var connectionId = SystemAPI.GetSingleton<NetworkId>().Value;
state.EntityManager.SetName(inputEntity, $"{nameof(MegacityThinInputSystem)}-RandInput");
state.EntityManager.AddComponent<PlayerVehicleInput>(inputEntity);
// NOTE: The buffer type might not be recognized in your IDE but it will be generated and Unity will recognize it.
// TODO : verify this buffer
//state.EntityManager.AddBuffer<Unity.Megacity.Gameplay.Generated.PlayerVehicleInputInputBufferData>(inputEntity);
state.EntityManager.AddComponentData(inputEntity, new GhostOwner { NetworkId = connectionId });
return; // Return as the EntityManager has now had a structural change, invalidating `commandTargetRw`.
}
// Recalculate AI action every x ticks:
var networkTime = SystemAPI.GetSingleton<NetworkTime>();
if (networkTime.ServerTick.TickIndexForValidTick % 30 == 0)
{
var input = state.EntityManager.GetComponentData<PlayerVehicleInput>(commandTargetRw.ValueRO.targetEntity);
var rand = m_Rand.Value;
// Movement:
input.ControlDirection = (rand.NextFloat3() * 2) - new float3(1);
input.GamepadDirection = (rand.NextFloat3() * 2) - new float3(1);
// Drive:
input.Acceleration = rand.NextInt() < 0.8f ? 1 : 0;
input.Brake = rand.NextInt() < 0.1f ? 1 : 0;
// Roll:
input.Roll = rand.NextFloat(-1f, 1f);
// Shooting:
input.Shoot = rand.NextInt() < 0.3f;
m_Rand.Value = rand;
state.EntityManager.SetComponentData(commandTargetRw.ValueRO.targetEntity, input);
}
}
}
}