浏览代码

Merge from the when_player_leaves branch.

/main/staging
nathaniel.buck@unity3d.com 2 年前
当前提交
7734e73f
共有 4 个文件被更改,包括 44 次插入19 次删除
  1. 13
      Assets/Scripts/Game/GameManager.cs
  2. 13
      Assets/Scripts/Lobby/LobbyAsyncRequests.cs
  3. 23
      Assets/Scripts/Relay/RelayUtpClient.cs
  4. 14
      Assets/Scripts/Relay/RelayUtpHost.cs

13
Assets/Scripts/Game/GameManager.cs


m_relaySetup = null;
}
if (m_relayClient != null)
{ Component.Destroy(m_relayClient);
m_relayClient = null;
{
m_relayClient.Dispose();
StartCoroutine(FinishCleanup());
// We need to delay slightly to give the disconnect message sent during Dispose time to reach the host, so that we don't destroy the connection without it being flushed first.
IEnumerator FinishCleanup()
{
yield return null;
Component.Destroy(m_relayClient);
m_relayClient = null;
}
}
}

13
Assets/Scripts/Lobby/LobbyAsyncRequests.cs


namespace LobbyRelaySample
{
/// <summary>
/// An abstraction layer between the direct calls into the Lobby API and the outcomes you actually want. E.g. you can request to get a readable list of
/// An abstraction layer between the direct calls into the Lobby API and the outcomes you actually want. E.g. you can request to get a readable list of
/// current lobbies and not need to make the query call directly.
/// </summary>
public class LobbyAsyncRequests

m_rateLimitQuery.EnqueuePendingOperation(caller);
return false;
}
Lobby lobby = m_lastKnownLobby;
if (lobby == null)
{

private float m_timeSinceLastCall = float.MaxValue;
private readonly float m_cooldownTime;
private Queue<Action> m_pendingOperations = new Queue<Action>();
private bool m_isHandlingPending = false; // Just in case a pending operation tries to enqueue itself again.
if (!m_isHandlingPending)
m_pendingOperations.Enqueue(action);
m_pendingOperations.Enqueue(action);
}
private bool m_isInCooldown = false;

private void OnUpdate(float dt)
{
m_timeSinceLastCall += dt;
m_isHandlingPending = false; // (Backup in case a pending operation hit an exception.)
if (m_timeSinceLastCall >= m_cooldownTime)
{
IsInCooldown = false;

m_isHandlingPending = true;
while (m_pendingOperations.Count > 0)
int numPending = m_pendingOperations.Count; // It's possible a pending operation will re-enqueue itself or new operations, which should wait until the next loop.
for (; numPending > 0; numPending--)
m_isHandlingPending = false;
}
}
}

23
Assets/Scripts/Relay/RelayUtpClient.cs


using System.Collections.Generic;
using System;
using System.Collections.Generic;
using Unity.Networking.Transport;
using UnityEngine;

/// This observes the local player and updates remote players over Relay when there are local changes, demonstrating basic data transfer over the Unity Transport (UTP).
/// Created after the connection to Relay has been confirmed.
/// </summary>
public class RelayUtpClient : MonoBehaviour // This is a MonoBehaviour merely to have access to Update.
public class RelayUtpClient : MonoBehaviour, IDisposable // This is a MonoBehaviour merely to have access to Update.
{
protected LobbyUser m_localUser;
protected LocalLobby m_localLobby;

protected bool m_hasSentInitialMessage = false;
private const float k_heartbeatPeriod = 5;
private bool m_hasDisposed = false;
protected enum MsgType { Ping = 0, NewPlayer, PlayerApprovalState, ReadyState, PlayerName, Emote, StartCountdown, CancelCountdown, ConfirmInGame, EndInGame, PlayerDisconnect }

m_localUser.onChanged -= OnLocalChange;
Leave();
Locator.Get.UpdateSlow.Unsubscribe(UpdateSlow);
m_connections.Clear();
m_networkDriver.Dispose();
// Don't clean up the NetworkDriver here, or else our disconnect message won't get through to the host. The host will handle cleaning up the connection.
}
public void Dispose()
{
if (!m_hasDisposed)
{
Uninitialize();
m_hasDisposed = true;
}
Uninitialize();
Dispose();
}
private void OnLocalChange(LobbyUser localUser)

// The host disconnected, and Relay does not support host migration. So, all clients should disconnect.
string msg;
if (m_IsRelayConnected)
msg = "Host disconnected! Leaving the lobby.";
msg = "The host disconnected! Leaving the lobby.";
else
msg = "Connection to host was lost. Leaving the lobby.";

14
Assets/Scripts/Relay/RelayUtpHost.cs


{
base.Uninitialize();
Locator.Get.Messenger.Unsubscribe(this);
m_networkDriver.Dispose();
}
protected override void OnUpdate()

OnNewConnection(conn, id);
else if (msgType == MsgType.PlayerDisconnect) // Clients message the host when they intend to disconnect, or else the host ends up keeping the connection open.
{
conn.Disconnect(m_networkDriver);
conn.Disconnect(m_networkDriver);
m_connections.Remove(conn);
LobbyAsyncRequests.Instance.GetRateLimit(LobbyAsyncRequests.RequestType.Query).EnqueuePendingOperation(WaitToCheckForUsers);
// The user ready status lives in the lobby data, which won't update immediately, but we need to use it to identify if all remaining players have readied.
// So, we'll wait two lobby update loops before we check remaining players to ensure the lobby has received the disconnect message.
void WaitToCheckForUsers()
{ LobbyAsyncRequests.Instance.GetRateLimit(LobbyAsyncRequests.RequestType.Query).EnqueuePendingOperation(CheckIfAllUsersReady);
}
}
// If a client has changed state, check if this changes whether all players have readied.

protected override void ProcessDisconnectEvent(NetworkConnection conn, DataStreamReader strm)
{
// When a disconnect from the host occurs, no additional action is required. This override just prevents the base behavior from occurring.
// TODO: If a client disconnects, see if remaining players are all already ready.
UnityEngine.Debug.LogError("Client disconnected!");
// We rely on the PlayerDisconnect message instead of this disconnect message since this message might not arrive for a long time after the disconnect actually occurs.
}
public void OnReceiveMessage(MessageType type, object msg)

正在加载...
取消
保存