浏览代码

Merging in QOL changes.

/main/staging
当前提交
7a207895
共有 24 个文件被更改,包括 83 次插入49 次删除
  1. 40
      Assets/Scripts/GameLobby/Game/GameManager.cs
  2. 4
      Assets/Scripts/GameLobby/Game/LobbyServiceDataObserver.cs
  3. 3
      Assets/Scripts/GameLobby/Game/LobbyUserObserver.cs
  4. 4
      Assets/Scripts/GameLobby/Game/LocalLobbyObserver.cs
  5. 4
      Assets/Scripts/GameLobby/Game/LocalMenuState.cs
  6. 2
      Assets/Scripts/GameLobby/Infrastructure/Messenger.cs
  7. 9
      Assets/Scripts/GameLobby/Lobby/LobbyAPIInterface.cs
  8. 8
      Assets/Scripts/GameLobby/Lobby/LobbyAsyncRequests.cs
  9. 4
      Assets/Scripts/GameLobby/Lobby/LobbyContentHeartbeat.cs
  10. 2
      Assets/Scripts/GameLobby/NGO/SetupInGame.cs
  11. 10
      Assets/Scripts/GameLobby/Relay/RelayAPIInterface.cs
  12. 3
      Assets/Scripts/GameLobby/Relay/RelayUtpClient.cs
  13. 1
      Assets/Scripts/GameLobby/Relay/RelayUtpHost.cs
  14. 4
      Assets/Scripts/GameLobby/Relay/RelayUtpSetup.cs
  15. 4
      Assets/Scripts/GameLobby/UI/BackButtonUI.cs
  16. 6
      Assets/Scripts/GameLobby/UI/GameStateVisibilityUI.cs
  17. 4
      Assets/Scripts/GameLobby/UI/JoinCreateLobbyUI.cs
  18. 6
      Assets/Scripts/GameLobby/UI/MainMenuUI.cs
  19. 2
      Assets/Scripts/GameLobby/UI/StartLobbyButtonUI.cs
  20. 8
      Assets/Scripts/GameLobby/Game/LocalMenuStateObserver.cs
  21. 4
      Assets/Scripts/GameLobby/Game/LocalGameStateObserver.cs
  22. 0
      /Assets/Scripts/GameLobby/Game/LocalMenuStateObserver.cs.meta
  23. 0
      /Assets/Scripts/GameLobby/Game/LocalMenuState.cs.meta
  24. 0
      /Assets/Scripts/GameLobby/Game/LocalMenuState.cs

40
Assets/Scripts/GameLobby/Game/GameManager.cs


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Serialization;
/// All the Data that is important gets updated in here, the GameManager in the mainScene has all the references
/// needed to run the game.
/// <summary>
/// The Observer/Observed Pattern is great for keeping the UI in Sync with the actual Values.
/// Each list below represents a single Observed class that gets updated by other parts of the code, and will
/// trigger the list of Observers that are looking for changes in that class.
///
/// The list is serialized, so you can navigate to the Observers via the Inspector to see who's watching.
/// </summary>
private List<LocalGameStateObserver> m_GameStateObservers = new List<LocalGameStateObserver>();
private List<LocalMenuStateObserver> m_LocalMenuStateObservers = new List<LocalMenuStateObserver>();
[SerializeField]
private List<LocalLobbyObserver> m_LocalLobbyObservers = new List<LocalLobbyObserver>();
[SerializeField]

#endregion
private LocalGameState m_localGameState = new LocalGameState();
private LocalMenuState m_LocalMenuState = new LocalMenuState();
private RelayUtpSetup m_relaySetup;
private RelayUtpClient m_relayClient;

private void BeginObservers()
{
foreach (var gameStateObs in m_GameStateObservers)
gameStateObs.BeginObserving(m_localGameState);
foreach (var gameStateObs in m_LocalMenuStateObservers)
gameStateObs.BeginObserving(m_LocalMenuState);
foreach (var serviceObs in m_LobbyServiceObservers)
serviceObs.BeginObserving(m_lobbyServiceData);
foreach (var lobbyObs in m_LocalLobbyObservers)

}
/// Primarily used for UI elements to communicate state changes, this will receive messages from arbitrary providers for user interactions.
/// The Messaging System handles most of the core Lobby Service calls, and catches the callbacks from those calls.
/// These In turn update the observed variables and propagates the events to the game.
/// When looking for the interactions, look up the MessageType and search for it in the code to see where it is used outside this script.
/// EG. Locator.Get.Messenger.OnReceiveMessage(MessageType.RenameRequest, name);
/// </summary>
public void OnReceiveMessage(MessageType type, object msg)
{

},
OnFailedJoin);
}
else if (type == MessageType.RenameRequest)
else if (type == MessageType.RenameRequest)
{
string name = (string)msg;
if (string.IsNullOrWhiteSpace(name))

}
m_localUser.DisplayName = (string)msg;
}
}
else if (type == MessageType.ClientUserApproved)
{ ConfirmApproval();
}

{ if (m_relayClient is RelayUtpHost)
(m_relayClient as RelayUtpHost).SendInGameState();
}
else if (type == MessageType.ChangeGameState)
else if (type == MessageType.ChangeMenuState)
{ SetGameState((GameState)msg);
}
else if (type == MessageType.ConfirmInGameState)

{ m_localLobby.State = LobbyState.Lobby;
SetUserLobbyState();
}
}
}
bool isLeavingLobby = (state == GameState.Menu || state == GameState.JoinMenu) && m_localGameState.State == GameState.Lobby;
m_localGameState.State = state;
bool isLeavingLobby = (state == GameState.Menu || state == GameState.JoinMenu) && m_LocalMenuState.State == GameState.Lobby;
m_LocalMenuState.State = state;
if (isLeavingLobby)
OnLeftLobby();
}

if (!didSucceed)
{ Debug.LogError("Vivox login failed! Retrying in 5s...");
StartCoroutine(RetryConnection(StartVivoxLogin, m_localLobby.LobbyID));
return;
}
}
}

if (!didSucceed)
{ Debug.LogError("Vivox connection failed! Retrying in 5s...");
StartCoroutine(RetryConnection(StartVivoxJoin, m_localLobby.LobbyID));
return;
}
}
}

4
Assets/Scripts/GameLobby/Game/LobbyServiceDataObserver.cs


namespace LobbyRelaySample
{
/// <summary>
/// Holds a LobbyServiceData value and notifies all subscribers when it has been changed.
/// Check the GameManager in the mainScene for the list of observers being used in the project.
/// </summary>
public class LobbyServiceDataObserver : ObserverBehaviour<LobbyServiceData> { }
}

3
Assets/Scripts/GameLobby/Game/LobbyUserObserver.cs


namespace LobbyRelaySample
{
/// <summary>
/// Holds an instance of a lobbyplayer, and implements hooks for the UI to interact with.
/// Holds a LobbyUser value and notifies all subscribers when it has been changed.
/// Check the GameManager in the mainScene for the list of observers being used in the project.
/// </summary>
public class LobbyUserObserver : ObserverBehaviour<LobbyUser> { }
}

4
Assets/Scripts/GameLobby/Game/LocalLobbyObserver.cs


namespace LobbyRelaySample
{
/// <summary>
/// Holds a LocalLobby value and notifies all subscribers when it has been changed.
/// Check the GameManager in the mainScene for the list of observers being used in the project.
/// </summary>
public class LocalLobbyObserver : ObserverBehaviour<LocalLobby> { }
}

4
Assets/Scripts/GameLobby/Game/LocalMenuState.cs


/// Awaits player input to change the local game data.
/// </summary>
[System.Serializable]
public class LocalGameState : Observed<LocalGameState>
public class LocalMenuState : Observed<LocalMenuState>
{
GameState m_State = GameState.Menu;

}
}
public override void CopyObserved(LocalGameState oldObserved)
public override void CopyObserved(LocalMenuState oldObserved)
{
if (m_State == oldObserved.State)
return;

2
Assets/Scripts/GameLobby/Infrastructure/Messenger.cs


QueryLobbies = 4,
QuickJoin = 5,
ChangeGameState = 100,
ChangeMenuState = 100,
ConfirmInGameState = 101,
LobbyUserStatus = 102,
UserSetEmote = 103,

9
Assets/Scripts/GameLobby/Lobby/LobbyAPIInterface.cs


AsyncRequestLobby.Instance.DoRequest(task, onComplete);
}
/// <summary>
/// Uupdates custom data to the lobby, for all to see.
/// </summary>
public static void UpdateLobbyAsync(string lobbyId, Dictionary<string, DataObject> data, bool shouldLock, Action<Lobby> onComplete)
{
UpdateLobbyOptions updateOptions = new UpdateLobbyOptions { Data = data , IsLocked = shouldLock};

public static void UpdatePlayerAsync(string lobbyId, string playerId, Dictionary<string, PlayerDataObject> data, Action<Lobby> onComplete, string allocationId)
public static void UpdatePlayerAsync(string lobbyId, string playerId, Dictionary<string, PlayerDataObject> data, Action<Lobby> onComplete, string allocationId, string connectionInfo)
AllocationId = allocationId
AllocationId = allocationId,
ConnectionInfo = connectionInfo
};
var task = Lobbies.Instance.UpdatePlayerAsync(lobbyId, playerId, updateOptions);
AsyncRequestLobby.Instance.DoRequest(task, onComplete);

8
Assets/Scripts/GameLobby/Lobby/LobbyAsyncRequests.cs


if (result != null)
m_lastKnownLobby = result; // Store the most up-to-date lobby now since we have it, instead of waiting for the next heartbeat.
onComplete?.Invoke();
}, null);
}, null, null);
public void UpdatePlayerRelayInfoAsync(string allocationId, Action onComplete)
public void UpdatePlayerRelayInfoAsync(string allocationId, string connectionInfo, Action onComplete)
if (!ShouldUpdateData(() => { UpdatePlayerRelayInfoAsync(allocationId, onComplete); }, onComplete, true)) // Do retry here since the RelayUtpSetup that called this might be destroyed right after this.
if (!ShouldUpdateData(() => { UpdatePlayerRelayInfoAsync(allocationId, connectionInfo, onComplete); }, onComplete, true)) // Do retry here since the RelayUtpSetup that called this might be destroyed right after this.
LobbyAPIInterface.UpdatePlayerAsync(m_lastKnownLobby.Id, playerId, new Dictionary<string, PlayerDataObject>(), (r) => { onComplete?.Invoke(); }, allocationId);
LobbyAPIInterface.UpdatePlayerAsync(m_lastKnownLobby.Id, playerId, new Dictionary<string, PlayerDataObject>(), (r) => { onComplete?.Invoke(); }, allocationId, connectionInfo);
}
/// <param name="data">Key-value pairs, which will overwrite any existing data for these keys. Presumed to be available to all lobby members but not publicly.</param>

4
Assets/Scripts/GameLobby/Lobby/LobbyContentHeartbeat.cs


if (!m_localUser.IsApproved && m_lifetime > k_approvalMaxTime)
{
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, "Connection attempt timed out!");
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeGameState, GameState.JoinMenu);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeMenuState, GameState.JoinMenu);
}
if (m_shouldPushData)

}
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, "Host left the lobby! Disconnecting...");
Locator.Get.Messenger.OnReceiveMessage(MessageType.EndGame, null);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeGameState, GameState.JoinMenu);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeMenuState, GameState.JoinMenu);
}
}
}

2
Assets/Scripts/GameLobby/NGO/SetupInGame.cs


}
}
else if (type == MessageType.ChangeGameState)
else if (type == MessageType.ChangeMenuState)
{
// Once we're in-game, any state change reflects the player leaving the game, so we should clean up.
OnGameEnd();

10
Assets/Scripts/GameLobby/Relay/RelayAPIInterface.cs


using System;
using Unity.Services.Relay.Models;
using UnityEngine;
using RelayService = Unity.Services.Relay.Relay;
using Unity.Services.Relay;
namespace LobbyRelaySample.relay
{

Debug.LogError("Relay returned a null Allocation. This might occur if the Relay service has an outage, if your cloud project ID isn't linked, or if your Relay package version is outdated.");
else
onComplete?.Invoke(response);
};
}
;
}
/// <summary>

Debug.LogError("Could not join async with Relay join code " + joinCode);
else
onComplete?.Invoke(response);
};
}
;
}
}
}

3
Assets/Scripts/GameLobby/Relay/RelayUtpClient.cs


/// <summary>
/// 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.
/// If you are using the Unity Networking Package, you can use their Relay instead of building your own packets.
/// </summary>
public class RelayUtpClient : MonoBehaviour, IDisposable // This is a MonoBehaviour merely to have access to Update.
{

Debug.LogError(msg);
Locator.Get.Messenger.OnReceiveMessage(MessageType.DisplayErrorPopup, msg);
Leave();
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeGameState, GameState.JoinMenu);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeMenuState, GameState.JoinMenu);
}
/// <summary>

1
Assets/Scripts/GameLobby/Relay/RelayUtpHost.cs


/// <summary>
/// In addition to maintaining a heartbeat with the Relay server to keep it from timing out, the host player must pass network events
/// from clients to all other clients, since they don't connect to each other.
/// If you are using the Unity Networking Package, you can use their Relay instead of building your own packets.
/// </summary>
public class RelayUtpHost : RelayUtpClient, IReceiveMessages
{

4
Assets/Scripts/GameLobby/Relay/RelayUtpSetup.cs


RelayUtpHost host = gameObject.AddComponent<RelayUtpHost>();
host.Initialize(m_networkDriver, m_connections, m_localUser, m_localLobby);
m_onJoinComplete(true, host);
LobbyAsyncRequests.Instance.UpdatePlayerRelayInfoAsync(m_allocation.AllocationId.ToString(), null);
LobbyAsyncRequests.Instance.UpdatePlayerRelayInfoAsync(m_allocation.AllocationId.ToString(), m_localLobby.RelayCode, null);
}
}
}

RelayUtpClient client = gameObject.AddComponent<RelayUtpClient>();
client.Initialize(m_networkDriver, m_connections, m_localUser, m_localLobby);
m_onJoinComplete(true, client);
LobbyAsyncRequests.Instance.UpdatePlayerRelayInfoAsync(m_allocation.AllocationId.ToString(), null);
LobbyAsyncRequests.Instance.UpdatePlayerRelayInfoAsync(m_allocation.AllocationId.ToString(), m_localLobby.RelayCode, null);
}
}
}

4
Assets/Scripts/GameLobby/UI/BackButtonUI.cs


{
public void ToJoinMenu()
{
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeGameState, GameState.JoinMenu);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeMenuState, GameState.JoinMenu);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeGameState, GameState.Menu);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeMenuState, GameState.Menu);
}
}
}

6
Assets/Scripts/GameLobby/UI/GameStateVisibilityUI.cs


/// <summary>
/// Show or hide a UI element based on the current GameState (e.g. in a lobby).
/// </summary>
[RequireComponent(typeof(LocalGameStateObserver))]
public class GameStateVisibilityUI : ObserverPanel<LocalGameState>
[RequireComponent(typeof(LocalMenuStateObserver))]
public class GameStateVisibilityUI : ObserverPanel<LocalMenuState>
public override void ObservedUpdated(LocalGameState observed)
public override void ObservedUpdated(LocalMenuState observed)
{
if (!ShowThisWhen.HasFlag(observed.State))
Hide();

4
Assets/Scripts/GameLobby/UI/JoinCreateLobbyUI.cs


/// <summary>
/// The panel that holds the lobby joining and creation panels.
/// </summary>
public class JoinCreateLobbyUI : ObserverPanel<LocalGameState>
public class JoinCreateLobbyUI : ObserverPanel<LocalMenuState>
{
public UnityEvent<JoinCreateTabs> m_OnTabChanged;

CurrentTab = JoinCreateTabs.Create;
}
public override void ObservedUpdated(LocalGameState observed)
public override void ObservedUpdated(LocalMenuState observed)
{
if (observed.State == GameState.JoinMenu)
{

6
Assets/Scripts/GameLobby/UI/MainMenuUI.cs


/// <summary>
/// Watches for changes in the game state to/from the main menu.
/// </summary>
[RequireComponent(typeof(LocalGameStateObserver))]
public class MainMenuUI : ObserverPanel<LocalGameState>
[RequireComponent(typeof(LocalMenuStateObserver))]
public class MainMenuUI : ObserverPanel<LocalMenuState>
public override void ObservedUpdated(LocalGameState observed)
public override void ObservedUpdated(LocalMenuState observed)
{
if (observed.State == GameState.Menu)
Show();

2
Assets/Scripts/GameLobby/UI/StartLobbyButtonUI.cs


{
public void ToJoinMenu()
{
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeGameState, GameState.JoinMenu);
Locator.Get.Messenger.OnReceiveMessage(MessageType.ChangeMenuState, GameState.JoinMenu);
}
}
}

8
Assets/Scripts/GameLobby/Game/LocalMenuStateObserver.cs


namespace LobbyRelaySample
{
/// <summary>
/// Holds a LocalMenuState value and notifies all subscribers when it has been changed.
/// Check the GameManager in the mainScene for the list of observers being used in the project.
/// </summary>
public class LocalMenuStateObserver : ObserverBehaviour<LocalMenuState> { }
}

4
Assets/Scripts/GameLobby/Game/LocalGameStateObserver.cs


namespace LobbyRelaySample
{
public class LocalGameStateObserver : ObserverBehaviour<LocalGameState> { }
}

/Assets/Scripts/GameLobby/Game/LocalGameStateObserver.cs.meta → /Assets/Scripts/GameLobby/Game/LocalMenuStateObserver.cs.meta

/Assets/Scripts/GameLobby/Game/LocalGameState.cs.meta → /Assets/Scripts/GameLobby/Game/LocalMenuState.cs.meta

/Assets/Scripts/GameLobby/Game/LocalGameState.cs → /Assets/Scripts/GameLobby/Game/LocalMenuState.cs

正在加载...
取消
保存