Skip to content

Commit 8e7ddab

Browse files
update
Adding the SinglePlayerTransport.
1 parent ea046c5 commit 8e7ddab

File tree

3 files changed

+156
-0
lines changed

3 files changed

+156
-0
lines changed

com.unity.netcode.gameobjects/Components/Transport.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using Unity.Netcode;
4+
5+
/// <summary>
6+
/// A transport that can be used to run a Netcode for GameObjects sessopm in "single player" mode
7+
/// by assigning this transport to the <see cref="NetworkConfig.NetworkTransport"/>
8+
/// property before starting a host.
9+
/// </summary>
10+
public class SinglePlayerTransport : NetworkTransport
11+
{
12+
/// <inheritdoc/>
13+
public override ulong ServerClientId { get; } = 0;
14+
15+
internal static string NotStartingAsHostErrorMessage = $"When using {nameof(SinglePlayerTransport)}, you must start a hosted session so both client and server are available locally.";
16+
17+
private struct MessageData
18+
{
19+
public ulong FromClientId;
20+
public ArraySegment<byte> Payload;
21+
public NetworkEvent Event;
22+
public float AvailableTime;
23+
}
24+
25+
private static Dictionary<ulong, Queue<MessageData>> s_MessageQueue = new Dictionary<ulong, Queue<MessageData>>();
26+
27+
private bool m_Initialized;
28+
private ulong m_TransportId = 0;
29+
private NetworkManager m_NetworkManager;
30+
31+
32+
/// <inheritdoc/>
33+
public override void Send(ulong clientId, ArraySegment<byte> payload, NetworkDelivery networkDelivery)
34+
{
35+
var copy = new byte[payload.Array.Length];
36+
Array.Copy(payload.Array, copy, payload.Array.Length);
37+
s_MessageQueue[clientId].Enqueue(new MessageData
38+
{
39+
FromClientId = m_TransportId,
40+
Payload = new ArraySegment<byte>(copy, payload.Offset, payload.Count),
41+
Event = NetworkEvent.Data,
42+
AvailableTime = (float)m_NetworkManager.LocalTime.FixedTime,
43+
});
44+
}
45+
46+
/// <inheritdoc/>
47+
public override NetworkEvent PollEvent(out ulong clientId, out ArraySegment<byte> payload, out float receiveTime)
48+
{
49+
if (s_MessageQueue[m_TransportId].Count > 0)
50+
{
51+
var data = s_MessageQueue[m_TransportId].Peek();
52+
if (data.AvailableTime > m_NetworkManager.LocalTime.FixedTime)
53+
{
54+
clientId = 0;
55+
payload = new ArraySegment<byte>();
56+
receiveTime = 0;
57+
return NetworkEvent.Nothing;
58+
}
59+
60+
s_MessageQueue[m_TransportId].Dequeue();
61+
clientId = data.FromClientId;
62+
payload = data.Payload;
63+
receiveTime = m_NetworkManager.LocalTime.TimeAsFloat;
64+
if (m_NetworkManager.IsServer && data.Event == NetworkEvent.Connect)
65+
{
66+
s_MessageQueue[data.FromClientId].Enqueue(new MessageData { Event = NetworkEvent.Connect, FromClientId = ServerClientId, Payload = new ArraySegment<byte>() });
67+
}
68+
return data.Event;
69+
}
70+
clientId = 0;
71+
payload = new ArraySegment<byte>();
72+
receiveTime = 0;
73+
return NetworkEvent.Nothing;
74+
}
75+
76+
/// <inheritdoc/>
77+
/// <remarks>
78+
/// This will always return false for <see cref="SinglePlayerTransport"/>.
79+
/// Always use <see cref="StartServer"/>.
80+
/// </remarks>
81+
public override bool StartClient()
82+
{
83+
NetworkLog.LogError(NotStartingAsHostErrorMessage);
84+
return false;
85+
}
86+
87+
/// <inheritdoc/>
88+
/// <remarks>
89+
/// Always use <see cref="NetworkManager.StartHost"/> when hosting a local single player session.
90+
/// </remarks>
91+
public override bool StartServer()
92+
{
93+
s_MessageQueue[ServerClientId] = new Queue<MessageData>();
94+
if (!m_NetworkManager.LocalClient.IsHost && m_NetworkManager.LocalClient.IsServer)
95+
{
96+
NetworkLog.LogError(NotStartingAsHostErrorMessage);
97+
return false;
98+
}
99+
return true;
100+
}
101+
102+
/// <inheritdoc/>
103+
public override void DisconnectRemoteClient(ulong clientId)
104+
{
105+
s_MessageQueue[clientId].Enqueue(new MessageData { Event = NetworkEvent.Disconnect, FromClientId = m_TransportId, Payload = new ArraySegment<byte>() });
106+
}
107+
108+
/// <inheritdoc/>
109+
public override void DisconnectLocalClient()
110+
{
111+
s_MessageQueue[ServerClientId].Enqueue(new MessageData { Event = NetworkEvent.Disconnect, FromClientId = m_TransportId, Payload = new ArraySegment<byte>() });
112+
}
113+
114+
/// <inheritdoc/>
115+
/// <remarks>
116+
/// Will always return 0 since this transport is for a local single player session.
117+
/// </remarks>
118+
public override ulong GetCurrentRtt(ulong clientId)
119+
{
120+
return 0;
121+
}
122+
123+
/// <inheritdoc/>
124+
public override void Shutdown()
125+
{
126+
s_MessageQueue.Clear();
127+
m_TransportId = 0;
128+
}
129+
130+
/// <inheritdoc/>
131+
public override void Initialize(NetworkManager networkManager = null)
132+
{
133+
s_MessageQueue.Clear();
134+
m_NetworkManager = networkManager;
135+
}
136+
}
137+

com.unity.netcode.gameobjects/Components/Transport/SinglePlayerTransport.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)