forked from Unity-Technologies/EntityComponentSystemSamples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathThinClientInputSystem.cs
More file actions
92 lines (80 loc) · 3.85 KB
/
Copy pathThinClientInputSystem.cs
File metadata and controls
92 lines (80 loc) · 3.85 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
using System;
using System.Diagnostics;
using Unity.Entities;
using Unity.NetCode;
namespace Samples.HelloNetcode
{
// This system should only run in thin client worlds (and normal input handling only in normal client worlds)
[UpdateInGroup(typeof(HelloNetcodeInputSystemGroup))]
[WorldSystemFilter(WorldSystemFilterFlags.ThinClientSimulation)]
public partial class ThinClientInputSystem : SystemBase
{
int m_FrameCount;
uint m_WorldIndex;
protected override void OnCreate()
{
RequireForUpdate<EnableThinClients>();
RequireForUpdate<EnableSpawnPlayer>();
RequireForUpdate<NetworkIdComponent>();
// Give every thin client some randomness
var rand = Unity.Mathematics.Random.CreateFromIndex((uint)Stopwatch.GetTimestamp());
m_FrameCount = rand.NextInt(100);
m_WorldIndex = UInt32.Parse(World.Name.Substring(World.Name.Length - 1));
}
protected override void OnUpdate()
{
// Check if the connection has no command target set yet, if not then create it (this is the dummy thin client player)
if (SystemAPI.TryGetSingleton<CommandTargetComponent>(out var commandTarget) && commandTarget.targetEntity == Entity.Null)
CreateThinClientPlayer();
byte left, right, up, down, jump;
left = right = up = down = jump = 0;
// Move in a random direction
var state = (int)(SystemAPI.Time.ElapsedTime+m_WorldIndex) % 4;
switch (state)
{
case 0: left = 1; break;
case 1: right = 1; break;
case 2: up = 1; break;
case 3: down = 1; break;
}
// Jump every 100th frame
if (++m_FrameCount % 100 == 0)
{
jump = 1;
m_FrameCount = 0;
}
// Thin clients do not spawn anything so there will be only one PlayerInput component
foreach (var inputData in SystemAPI.Query<RefRW<CharacterControllerPlayerInput>>())
{
inputData.ValueRW = default;
if (jump == 1)
inputData.ValueRW.Jump.Set();
if (left == 1)
inputData.ValueRW.Movement.x -= 1;
if (right == 1)
inputData.ValueRW.Movement.x += 1;
if (down == 1)
inputData.ValueRW.Movement.y -= 1;
if (up == 1)
inputData.ValueRW.Movement.y += 1;
}
}
void CreateThinClientPlayer()
{
// Create dummy entity to store the thin clients inputs
// When using IInputComponentData the entity will need the input component and its generated
// buffer, the GhostOwnerComponent set up with the local connection ID and finally the
// CommandTargetComponent needs to be manually set.
var ent = EntityManager.CreateEntity();
EntityManager.AddComponent<CharacterControllerPlayerInput>(ent);
var connectionId = SystemAPI.GetSingleton<NetworkIdComponent>().Value;
EntityManager.AddComponentData(ent, new GhostOwnerComponent() { NetworkId = connectionId });
// NOTE: The buffer type might not be recognized in your IDE but it will be generated and Unity will recognize it
EntityManager.AddComponent<HelloNetcodeSamples.Generated.CharacterControllerPlayerInputInputBufferData>(ent);
// NOTE: The server also has to manually set the command target for the thin client player
// even though auto command target is used on the player prefab (and normal clients), see
// SpawnPlayerSystem.
SystemAPI.SetSingleton(new CommandTargetComponent { targetEntity = ent });
}
}
}