Initial commit
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using XRMultiplayer;
|
||||
|
||||
public class GreetingBoardUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] TMP_Text m_RoomNameText;
|
||||
[SerializeField] TMP_Text m_RoomCodeText;
|
||||
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Subscribe(ConnectedToGame);
|
||||
XRINetworkGameManager.ConnectedRoomName.Subscribe(UpdateRoomName);
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Unsubscribe(ConnectedToGame);
|
||||
XRINetworkGameManager.ConnectedRoomName.Unsubscribe(UpdateRoomName);
|
||||
}
|
||||
|
||||
void ConnectedToGame(bool connected)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
m_RoomNameText.text = XRINetworkGameManager.ConnectedRoomName.Value;
|
||||
m_RoomCodeText.text = XRINetworkGameManager.ConnectedRoomCode;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateRoomName(string roomName)
|
||||
{
|
||||
m_RoomNameText.text = roomName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1098bf099acef3146972ca69711ad10e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,38 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
using UnityEngine.UI;
|
||||
|
||||
public class IntButtonUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] UnityEvent<int> m_ValueUpdated;
|
||||
[SerializeField] Vector2Int m_MinMaxValue;
|
||||
[SerializeField] Button m_IncrementButton;
|
||||
[SerializeField] Button m_DecrementButton;
|
||||
|
||||
[SerializeField] int m_UpdateValue = 1;
|
||||
[SerializeField] int m_CurrentValue;
|
||||
[SerializeField] TMP_Text m_CurrentValueText;
|
||||
|
||||
void Start()
|
||||
{
|
||||
m_IncrementButton.onClick.AddListener(() => UpdateValue(true));
|
||||
m_DecrementButton.onClick.AddListener(() => UpdateValue(false));
|
||||
|
||||
m_CurrentValueText.text = m_CurrentValue.ToString();
|
||||
m_ValueUpdated.Invoke(m_CurrentValue);
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
m_IncrementButton.onClick.RemoveAllListeners();
|
||||
m_DecrementButton.onClick.RemoveAllListeners();
|
||||
}
|
||||
|
||||
public void UpdateValue(bool increment)
|
||||
{
|
||||
m_CurrentValue = Mathf.Clamp(m_CurrentValue + (increment ? m_UpdateValue : -m_UpdateValue), m_MinMaxValue.x, m_MinMaxValue.y);
|
||||
m_CurrentValueText.text = m_CurrentValue.ToString();
|
||||
m_ValueUpdated.Invoke(m_CurrentValue);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e5ee7243e97cfc94886f889d4feec531
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ade11e29343c0e743952dbfa39cc76e3
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
using TMPro;
|
||||
using Unity.Services.Lobbies.Models;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class LobbyListSlotUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] TMP_Text m_RoomNameText;
|
||||
[SerializeField] TMP_Text m_PlayerCountText;
|
||||
[SerializeField] Button m_JoinButton;
|
||||
[SerializeField] GameObject m_FullImage;
|
||||
[SerializeField] TMP_Text m_StatusText;
|
||||
[SerializeField] GameObject m_JoinImage;
|
||||
|
||||
LobbyUI m_LobbyListUI;
|
||||
Lobby m_Lobby;
|
||||
|
||||
bool m_NonJoinable = false;
|
||||
|
||||
public void CreateLobbyUI(Lobby lobby, LobbyUI lobbyListUI)
|
||||
{
|
||||
m_NonJoinable = false;
|
||||
m_Lobby = lobby;
|
||||
m_LobbyListUI = lobbyListUI;
|
||||
m_JoinButton.onClick.AddListener(JoinRoom);
|
||||
m_RoomNameText.text = lobby.Name;
|
||||
m_PlayerCountText.text = $"{lobby.Players.Count}/{lobby.MaxPlayers}";
|
||||
|
||||
m_FullImage.SetActive(false);
|
||||
m_JoinImage.SetActive(false);
|
||||
}
|
||||
|
||||
public void CreateNonJoinableLobbyUI(Lobby lobby, LobbyUI lobbyListUI, string statusText)
|
||||
{
|
||||
m_NonJoinable = true;
|
||||
m_JoinButton.interactable = false;
|
||||
m_Lobby = lobby;
|
||||
m_LobbyListUI = lobbyListUI;
|
||||
m_RoomNameText.text = lobby.Name;
|
||||
m_StatusText.text = statusText;
|
||||
m_FullImage.SetActive(true);
|
||||
m_JoinImage.SetActive(false);
|
||||
}
|
||||
|
||||
public void ToggleHover(bool toggle)
|
||||
{
|
||||
if (m_NonJoinable) return;
|
||||
if (toggle)
|
||||
{
|
||||
if (m_Lobby.AvailableSlots <= 0)
|
||||
{
|
||||
m_JoinImage.SetActive(false);
|
||||
m_FullImage.SetActive(true);
|
||||
m_JoinButton.interactable = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_JoinImage.SetActive(true);
|
||||
m_FullImage.SetActive(false);
|
||||
m_JoinButton.interactable = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_FullImage.SetActive(false);
|
||||
m_JoinImage.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
m_JoinButton.onClick.RemoveListener(JoinRoom);
|
||||
}
|
||||
|
||||
void JoinRoom()
|
||||
{
|
||||
m_LobbyListUI.JoinLobby(m_Lobby);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a58f90d258cea424b9a5a0a9de66d8c3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,309 @@
|
||||
using System.Collections;
|
||||
using Unity.Services.Lobbies.Models;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using TMPro;
|
||||
using WebSocketSharp;
|
||||
using Unity.Services.Vivox;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class LobbyUI : MonoBehaviour
|
||||
{
|
||||
[Header("Lobby List")]
|
||||
[SerializeField] Transform m_LobbyListParent;
|
||||
[SerializeField] GameObject m_LobbyListPrefab;
|
||||
[SerializeField] Button m_RefreshButton;
|
||||
[SerializeField] Image m_CooldownImage;
|
||||
[SerializeField] float m_AutoRefreshTime = 5.0f;
|
||||
[SerializeField] float m_RefreshCooldownTime = .5f;
|
||||
|
||||
[Header("Connection Texts")]
|
||||
[SerializeField] TMP_Text m_ConnectionUpdatedText;
|
||||
[SerializeField] TMP_Text m_ConnectionSuccessText;
|
||||
[SerializeField] TMP_Text m_ConnectionFailedText;
|
||||
|
||||
[Header("Room Creation")]
|
||||
[SerializeField] TMP_InputField m_RoomNameText;
|
||||
[SerializeField] Toggle m_PrivacyToggle;
|
||||
|
||||
[SerializeField] GameObject[] m_ConnectionSubPanels;
|
||||
|
||||
VoiceChatManager m_VoiceChatManager;
|
||||
|
||||
Coroutine m_UpdateLobbiesRoutine;
|
||||
Coroutine m_CooldownFillRoutine;
|
||||
|
||||
bool m_Private = false;
|
||||
int m_PlayerCount;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_VoiceChatManager = FindFirstObjectByType<VoiceChatManager>();
|
||||
LobbyManager.status.Subscribe(ConnectedUpdated);
|
||||
m_CooldownImage.enabled = false;
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
m_PrivacyToggle.onValueChanged.AddListener(TogglePrivacy);
|
||||
|
||||
m_PlayerCount = XRINetworkGameManager.maxPlayers / 2;
|
||||
|
||||
XRINetworkGameManager.Instance.connectionFailedAction += FailedToConnect;
|
||||
XRINetworkGameManager.Instance.connectionUpdated += ConnectedUpdated;
|
||||
|
||||
foreach (Transform t in m_LobbyListParent)
|
||||
{
|
||||
Destroy(t.gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
CheckInternetAsync();
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
HideLobbies();
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
XRINetworkGameManager.Instance.connectionFailedAction -= FailedToConnect;
|
||||
XRINetworkGameManager.Instance.connectionUpdated -= ConnectedUpdated;
|
||||
|
||||
LobbyManager.status.Unsubscribe(ConnectedUpdated);
|
||||
}
|
||||
public async void CheckInternetAsync()
|
||||
{
|
||||
if (!XRINetworkGameManager.Instance.IsAuthenticated())
|
||||
{
|
||||
ToggleConnectionSubPanel(5);
|
||||
await XRINetworkGameManager.Instance.Authenticate();
|
||||
}
|
||||
CheckForInternet();
|
||||
}
|
||||
|
||||
void CheckForInternet()
|
||||
{
|
||||
if (Application.internetReachability == NetworkReachability.NotReachable)
|
||||
{
|
||||
ToggleConnectionSubPanel(5);
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleConnectionSubPanel(0);
|
||||
}
|
||||
}
|
||||
|
||||
public void CreateLobby()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Subscribe(OnConnected);
|
||||
if (m_RoomNameText.text.IsNullOrEmpty() || m_RoomNameText.text == "<Room Name>")
|
||||
{
|
||||
m_RoomNameText.text = $"{XRINetworkGameManager.LocalPlayerName.Value}'s Room";
|
||||
}
|
||||
XRINetworkGameManager.Instance.CreateNewLobby(m_RoomNameText.text, m_Private, m_PlayerCount);
|
||||
m_ConnectionSuccessText.text = $"Joining {m_RoomNameText.text}";
|
||||
}
|
||||
|
||||
public void UpdatePlayerCount(int count)
|
||||
{
|
||||
m_PlayerCount = Mathf.Clamp(count, 1, XRINetworkGameManager.maxPlayers);
|
||||
}
|
||||
|
||||
public void CancelConnection()
|
||||
{
|
||||
XRINetworkGameManager.Instance.CancelMatchmaking();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set the room name
|
||||
/// </summary>
|
||||
/// <param name="roomName">The name of the room</param>
|
||||
/// <remarks> This function is called from <see cref="XRIKeyboardDisplay"/>
|
||||
public void SetRoomName(string roomName)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(roomName))
|
||||
{
|
||||
m_RoomNameText.text = roomName;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Join a room by code
|
||||
/// </summary>
|
||||
/// <param name="roomCode">The room code to join</param>
|
||||
/// <remarks> This function is called from <see cref="XRIKeyboardDisplay"/>
|
||||
public void EnterRoomCode(string roomCode)
|
||||
{
|
||||
ToggleConnectionSubPanel(2);
|
||||
XRINetworkGameManager.Connected.Subscribe(OnConnected);
|
||||
XRINetworkGameManager.Instance.JoinLobbyByCode(roomCode.ToUpper());
|
||||
m_ConnectionSuccessText.text = $"Joining Room: {roomCode.ToUpper()}";
|
||||
}
|
||||
|
||||
public void JoinLobby(Lobby lobby)
|
||||
{
|
||||
ToggleConnectionSubPanel(2);
|
||||
XRINetworkGameManager.Connected.Subscribe(OnConnected);
|
||||
XRINetworkGameManager.Instance.JoinLobbySpecific(lobby);
|
||||
m_ConnectionSuccessText.text = $"Joining {lobby.Name}";
|
||||
}
|
||||
|
||||
public void QuickJoinLobby()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Subscribe(OnConnected);
|
||||
XRINetworkGameManager.Instance.QuickJoinLobby();
|
||||
m_ConnectionSuccessText.text = "Joining Random";
|
||||
}
|
||||
|
||||
public void SetVoiceChatAudidibleDistance(int audibleDistance)
|
||||
{
|
||||
if (audibleDistance <= m_VoiceChatManager.ConversationalDistance)
|
||||
{
|
||||
audibleDistance = m_VoiceChatManager.ConversationalDistance + 1;
|
||||
}
|
||||
m_VoiceChatManager.AudibleDistance = audibleDistance;
|
||||
}
|
||||
|
||||
public void SetVoiceChatConversationalDistance(int conversationalDistance)
|
||||
{
|
||||
m_VoiceChatManager.ConversationalDistance = conversationalDistance;
|
||||
}
|
||||
|
||||
public void SetVoiceChatAudioFadeIntensity(float fadeIntensity)
|
||||
{
|
||||
m_VoiceChatManager.AudioFadeIntensity = fadeIntensity;
|
||||
}
|
||||
|
||||
public void SetVoiceChatAudioFadeModel(int fadeModel)
|
||||
{
|
||||
m_VoiceChatManager.AudioFadeModel = (AudioFadeModel)fadeModel;
|
||||
}
|
||||
|
||||
public void TogglePrivacy(bool toggle)
|
||||
{
|
||||
m_Private = toggle;
|
||||
}
|
||||
|
||||
public void ToggleConnectionSubPanel(int panelId)
|
||||
{
|
||||
for (int i = 0; i < m_ConnectionSubPanels.Length; i++)
|
||||
{
|
||||
m_ConnectionSubPanels[i].SetActive(i == panelId);
|
||||
}
|
||||
|
||||
|
||||
if (panelId == 0)
|
||||
{
|
||||
ShowLobbies();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideLobbies();
|
||||
}
|
||||
}
|
||||
|
||||
void OnConnected(bool connected)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
ToggleConnectionSubPanel(3);
|
||||
XRINetworkGameManager.Connected.Unsubscribe(OnConnected);
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectedUpdated(string update)
|
||||
{
|
||||
m_ConnectionUpdatedText.text = $"<b>Status:</b> {update}";
|
||||
}
|
||||
|
||||
public void FailedToConnect(string reason)
|
||||
{
|
||||
ToggleConnectionSubPanel(4);
|
||||
m_ConnectionFailedText.text = $"<b>Error:</b> {reason}";
|
||||
}
|
||||
|
||||
public void HideLobbies()
|
||||
{
|
||||
EnableRefresh();
|
||||
if (m_UpdateLobbiesRoutine != null) StopCoroutine(m_UpdateLobbiesRoutine);
|
||||
}
|
||||
|
||||
public void ShowLobbies()
|
||||
{
|
||||
GetAllLobbies();
|
||||
if (m_UpdateLobbiesRoutine != null) StopCoroutine(m_UpdateLobbiesRoutine);
|
||||
m_UpdateLobbiesRoutine = StartCoroutine(UpdateAvailableLobbies());
|
||||
}
|
||||
|
||||
IEnumerator UpdateAvailableLobbies()
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
yield return new WaitForSeconds(m_AutoRefreshTime);
|
||||
GetAllLobbies();
|
||||
}
|
||||
}
|
||||
|
||||
void EnableRefresh()
|
||||
{
|
||||
m_CooldownImage.enabled = false;
|
||||
m_RefreshButton.interactable = true;
|
||||
}
|
||||
|
||||
IEnumerator UpdateButtonCooldown()
|
||||
{
|
||||
m_RefreshButton.interactable = false;
|
||||
|
||||
m_CooldownImage.enabled = true;
|
||||
for (float i = 0; i < m_RefreshCooldownTime; i += Time.deltaTime)
|
||||
{
|
||||
m_CooldownImage.fillAmount = Mathf.Clamp01(i / m_RefreshCooldownTime);
|
||||
yield return null;
|
||||
}
|
||||
EnableRefresh();
|
||||
}
|
||||
|
||||
async void GetAllLobbies()
|
||||
{
|
||||
if (m_CooldownImage.enabled || (int)XRINetworkGameManager.CurrentConnectionState.Value < 2) return;
|
||||
if (m_CooldownFillRoutine != null) StopCoroutine(m_CooldownFillRoutine);
|
||||
m_CooldownFillRoutine = StartCoroutine(UpdateButtonCooldown());
|
||||
|
||||
QueryResponse lobbies = await LobbyManager.GetLobbiesAsync();
|
||||
|
||||
foreach (Transform t in m_LobbyListParent)
|
||||
{
|
||||
Destroy(t.gameObject);
|
||||
}
|
||||
|
||||
if (lobbies.Results != null || lobbies.Results.Count > 0)
|
||||
{
|
||||
foreach (var lobby in lobbies.Results)
|
||||
{
|
||||
if (LobbyManager.CheckForLobbyFilter(lobby))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LobbyManager.CheckForIncompatibilityFilter(lobby))
|
||||
{
|
||||
LobbyListSlotUI newLobbyUI = Instantiate(m_LobbyListPrefab, m_LobbyListParent).GetComponent<LobbyListSlotUI>();
|
||||
newLobbyUI.CreateNonJoinableLobbyUI(lobby, this, "Version Conflict");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (LobbyManager.CanJoinLobby(lobby))
|
||||
{
|
||||
LobbyListSlotUI newLobbyUI = Instantiate(m_LobbyListPrefab, m_LobbyListParent).GetComponent<LobbyListSlotUI>();
|
||||
newLobbyUI.CreateLobbyUI(lobby, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: edb76344e1e0b364ca7e1ac930bfd949
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,130 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class OfflineMenu : MonoBehaviour
|
||||
{
|
||||
/// <summary>
|
||||
/// Colors to choose from for the player.
|
||||
/// </summary>
|
||||
[SerializeField, Tooltip("Default name for the player")] Color[] m_PlayerColors;
|
||||
|
||||
[Header("Player Info")]
|
||||
/// <summary>
|
||||
/// Default name for the player.
|
||||
/// </summary>
|
||||
[SerializeField, Tooltip("Default name for the player")] string m_DefaultPlayerName = "Unity Creator";
|
||||
[SerializeField] TMP_Text m_PlayerNameText;
|
||||
[SerializeField] TMP_Text m_PlayerInitialText;
|
||||
[SerializeField] Image[] m_PlayerColorIcons;
|
||||
[SerializeField] Image m_VolumeIndicator;
|
||||
[SerializeField] Image m_MicIcon;
|
||||
[SerializeField] Sprite m_MutedSprite;
|
||||
[SerializeField] Sprite m_UnmutedSprite;
|
||||
|
||||
[Header("Panel Objects")]
|
||||
[SerializeField] GameObject m_CustomizationPanel;
|
||||
[SerializeField] GameObject m_ConnectionPanel;
|
||||
|
||||
VoiceChatManager m_VoiceChatManager;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Subscribe(OnConnected);
|
||||
XRINetworkGameManager.LocalPlayerName.Subscribe(SetPlayerName);
|
||||
XRINetworkGameManager.LocalPlayerColor.Subscribe(SetPlayerColor);
|
||||
|
||||
OfflinePlayerAvatar.voiceAmp.Subscribe(UpdateMicIcon);
|
||||
|
||||
m_VoiceChatManager = FindFirstObjectByType<VoiceChatManager>();
|
||||
m_VoiceChatManager.selfMuted.Subscribe(MutedChanged);
|
||||
SetupPlayerDefaults();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
ShowCustomization();
|
||||
XRINetworkGameManager.Instance.connectionFailedAction += ConnectionFailed;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Unsubscribe(OnConnected);
|
||||
XRINetworkGameManager.LocalPlayerName.Unsubscribe(SetPlayerName);
|
||||
XRINetworkGameManager.LocalPlayerColor.Unsubscribe(SetPlayerColor);
|
||||
OfflinePlayerAvatar.voiceAmp.Unsubscribe(UpdateMicIcon);
|
||||
m_VoiceChatManager.selfMuted.Subscribe(MutedChanged);
|
||||
|
||||
XRINetworkGameManager.Instance.connectionFailedAction -= ConnectionFailed;
|
||||
}
|
||||
|
||||
void SetupPlayerDefaults()
|
||||
{
|
||||
XRINetworkGameManager.LocalPlayerName.Value = m_DefaultPlayerName;
|
||||
XRINetworkGameManager.LocalPlayerColor.Value = m_PlayerColors[Random.Range(0, m_PlayerColors.Length)];
|
||||
}
|
||||
|
||||
void SetPlayerName(string name)
|
||||
{
|
||||
if (name == string.Empty)
|
||||
{
|
||||
SetupPlayerDefaults();
|
||||
return;
|
||||
}
|
||||
|
||||
m_PlayerNameText.text = name;
|
||||
m_PlayerInitialText.text = name.Substring(0, 1);
|
||||
m_PlayerNameText.rectTransform.sizeDelta = new Vector2(m_PlayerNameText.preferredWidth * .25f, m_PlayerNameText.rectTransform.sizeDelta.y);
|
||||
}
|
||||
|
||||
void SetPlayerColor(Color color)
|
||||
{
|
||||
foreach (var c in m_PlayerColorIcons)
|
||||
{
|
||||
c.color = color;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateMicIcon(float amp)
|
||||
{
|
||||
m_VolumeIndicator.fillAmount = amp;
|
||||
}
|
||||
|
||||
void ShowCustomization()
|
||||
{
|
||||
m_CustomizationPanel.SetActive(true);
|
||||
m_ConnectionPanel.SetActive(false);
|
||||
}
|
||||
|
||||
public void CompleteCustomization()
|
||||
{
|
||||
m_CustomizationPanel.SetActive(false);
|
||||
m_ConnectionPanel.SetActive(true);
|
||||
}
|
||||
|
||||
void OnConnected(bool connected)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
m_CustomizationPanel.SetActive(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
gameObject.SetActive(true);
|
||||
ShowCustomization();
|
||||
}
|
||||
}
|
||||
|
||||
void MutedChanged(bool muted)
|
||||
{
|
||||
m_MicIcon.sprite = muted ? m_MutedSprite : m_UnmutedSprite;
|
||||
}
|
||||
|
||||
void ConnectionFailed(string reason)
|
||||
{
|
||||
CompleteCustomization();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 85c6e0a207dcbdd46980e3b8242c0f51
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0ca5a703d620af4bbac133f60dd60e8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class PlayerListInitializer : MonoBehaviour
|
||||
{
|
||||
[SerializeField] PlayerListUI[] m_PlayerListUIs;
|
||||
|
||||
void Start()
|
||||
{
|
||||
foreach (var l in m_PlayerListUIs)
|
||||
{
|
||||
l.InitializeCallbacks();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7bee81ae8e4186d45a1a593720a17674
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,131 @@
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class PlayerListUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] TMP_Text m_PlayerCountText;
|
||||
[SerializeField] Transform m_ConnectedPlayersViewportContentTransform;
|
||||
[SerializeField] GameObject m_PlayerSlotPrefab;
|
||||
|
||||
[SerializeField] bool m_AutoInitializeCallbacks = true;
|
||||
|
||||
readonly Dictionary<PlayerSlot, XRINetworkPlayer> m_PlayerDictionary = new();
|
||||
|
||||
bool m_CallbacksInitialized = false;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (!m_CallbacksInitialized && m_AutoInitializeCallbacks)
|
||||
InitializeCallbacks();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (XRINetworkGameManager.Connected.Value)
|
||||
{
|
||||
foreach (var kvp in m_PlayerDictionary)
|
||||
{
|
||||
kvp.Key.voiceChatFillImage.fillAmount = kvp.Value.playerVoiceAmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnDestroy()
|
||||
{
|
||||
XRINetworkGameManager.Instance.playerStateChanged -= ConnectedPlayerStateChange;
|
||||
XRINetworkGameManager.Connected.Unsubscribe(OnConnected);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Use this function to initialize the callbacks on objects that start out disabled or inactive.
|
||||
/// </summary>
|
||||
public void InitializeCallbacks()
|
||||
{
|
||||
if (m_CallbacksInitialized) return;
|
||||
m_CallbacksInitialized = true;
|
||||
|
||||
//Remove Prefab placeholders
|
||||
foreach (Transform t in m_ConnectedPlayersViewportContentTransform)
|
||||
{
|
||||
Destroy(t.gameObject);
|
||||
}
|
||||
|
||||
XRINetworkGameManager.Instance.playerStateChanged += ConnectedPlayerStateChange;
|
||||
XRINetworkGameManager.Connected.Subscribe(OnConnected);
|
||||
}
|
||||
|
||||
void OnConnected(bool connected)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
foreach (Transform t in m_ConnectedPlayersViewportContentTransform)
|
||||
{
|
||||
Destroy(t.gameObject);
|
||||
}
|
||||
|
||||
m_PlayerDictionary.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectedPlayerStateChange(ulong playerId, bool connected)
|
||||
{
|
||||
if (connected)
|
||||
{
|
||||
SetupPlayerSlotUI(playerId);
|
||||
}
|
||||
else
|
||||
{
|
||||
RemovePlayerSlotUI(playerId);
|
||||
}
|
||||
}
|
||||
|
||||
void RemovePlayerSlotUI(ulong playerId)
|
||||
{
|
||||
PlayerSlot slotToRemove = null;
|
||||
foreach (PlayerSlot slot in m_PlayerDictionary.Keys)
|
||||
{
|
||||
if (slot.playerID == playerId)
|
||||
{
|
||||
slotToRemove = slot;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (slotToRemove != null)
|
||||
{
|
||||
m_PlayerDictionary.Remove(slotToRemove);
|
||||
Destroy(slotToRemove.gameObject);
|
||||
m_PlayerCountText.text = $"{m_PlayerDictionary.Keys.Count}/{XRINetworkGameManager.Instance.lobbyManager.connectedLobby.MaxPlayers}";
|
||||
}
|
||||
}
|
||||
|
||||
void SetupPlayerSlotUI(ulong playerId)
|
||||
{
|
||||
PlayerSlot slot = Instantiate(m_PlayerSlotPrefab, m_ConnectedPlayersViewportContentTransform).GetComponent<PlayerSlot>();
|
||||
slot.playerID = playerId;
|
||||
|
||||
if (XRINetworkGameManager.Instance.GetPlayerByID(playerId, out XRINetworkPlayer player))
|
||||
{
|
||||
if (m_PlayerDictionary.TryAdd(slot, player))
|
||||
{
|
||||
slot.Setup(player);
|
||||
|
||||
if (player.IsLocalPlayer)
|
||||
{
|
||||
slot.playerSlotName.text += " (You)";
|
||||
}
|
||||
slot.playerIconImage.color = player.playerColor;
|
||||
|
||||
m_PlayerCountText.text = $"{m_PlayerDictionary.Keys.Count}/{XRINetworkGameManager.Instance.lobbyManager.connectedLobby.MaxPlayers}";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Utils.Log($"Player with id {playerId} is null. This is a bug.", 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 890d351bcb11f5245838066b83e72d7c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,92 @@
|
||||
using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using WebSocketSharp;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class PlayerSlot : MonoBehaviour
|
||||
{
|
||||
public TMP_Text playerSlotName;
|
||||
public TMP_Text playerInitial;
|
||||
public Image playerIconImage;
|
||||
|
||||
[Header("Mic Button")]
|
||||
public Image voiceChatFillImage;
|
||||
[SerializeField] Button m_MicButton;
|
||||
[SerializeField] Image m_PlayerVoiceIcon;
|
||||
[SerializeField] Image m_SquelchedIcon;
|
||||
[SerializeField] Sprite[] micIcons;
|
||||
XRINetworkPlayer m_Player;
|
||||
internal ulong playerID = 0;
|
||||
|
||||
public void Setup(XRINetworkPlayer player)
|
||||
{
|
||||
m_Player = player;
|
||||
m_Player.onColorUpdated += UpdateColor;
|
||||
m_Player.onNameUpdated += UpdateName;
|
||||
m_Player.selfMuted.OnValueChanged += UpdateSelfMutedState;
|
||||
m_MicButton.onClick.AddListener(Squelch);
|
||||
m_Player.squelched.Subscribe(UpdateSquelchedState);
|
||||
m_SquelchedIcon.enabled = false;
|
||||
if (m_Player.IsLocalPlayer)
|
||||
{
|
||||
m_MicButton.interactable = false;
|
||||
}
|
||||
|
||||
if (m_Player.selfMuted.Value)
|
||||
{
|
||||
m_PlayerVoiceIcon.sprite = micIcons[1];
|
||||
}
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
m_Player.onColorUpdated -= UpdateColor;
|
||||
m_Player.onNameUpdated -= UpdateName;
|
||||
m_Player.selfMuted.OnValueChanged -= UpdateSelfMutedState;
|
||||
m_MicButton.onClick.RemoveListener(Squelch);
|
||||
m_Player.squelched.Unsubscribe(UpdateSquelchedState);
|
||||
}
|
||||
|
||||
void UpdateColor(Color newColor)
|
||||
{
|
||||
playerIconImage.color = newColor;
|
||||
}
|
||||
|
||||
void UpdateName(string newName)
|
||||
{
|
||||
if (!newName.IsNullOrEmpty())
|
||||
{
|
||||
string playerName = newName;
|
||||
if (m_Player.IsLocalPlayer)
|
||||
{
|
||||
playerName += " (You)";
|
||||
}
|
||||
else if (m_Player.IsOwnedByServer)
|
||||
{
|
||||
playerName += " (Host)";
|
||||
}
|
||||
playerSlotName.text = playerName;
|
||||
playerInitial.text = newName.Substring(0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
#region Muting
|
||||
public void Squelch()
|
||||
{
|
||||
m_Player.ToggleSquelch();
|
||||
}
|
||||
|
||||
void UpdateSelfMutedState(bool old, bool current)
|
||||
{
|
||||
m_PlayerVoiceIcon.sprite = micIcons[current ? 1 : 0];
|
||||
}
|
||||
|
||||
void UpdateSquelchedState(bool squelched)
|
||||
{
|
||||
m_SquelchedIcon.enabled = squelched;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7282738eeb6afb24e9419b8ff287a61e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,304 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Audio;
|
||||
using TMPro;
|
||||
using System;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Samples.StarterAssets;
|
||||
using UnityEngine.InputSystem;
|
||||
using UnityEngine.XR.Interaction.Toolkit.Locomotion.Turning;
|
||||
using UnityEngine.Android;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
[DefaultExecutionOrder(100)]
|
||||
public class PlayerOptions : MonoBehaviour
|
||||
{
|
||||
[SerializeField] InputActionReference m_ToggleMenuAction;
|
||||
[SerializeField] AudioMixer m_Mixer;
|
||||
|
||||
[Header("Panels")]
|
||||
[SerializeField] GameObject m_HostRoomPanel;
|
||||
[SerializeField] GameObject m_ClientRoomPanel;
|
||||
[SerializeField] GameObject[] m_OfflineWarningPanels;
|
||||
[SerializeField] GameObject[] m_OnlinePanels;
|
||||
[SerializeField] GameObject[] m_Panels;
|
||||
[SerializeField] Toggle[] m_PanelToggles;
|
||||
|
||||
[Header("Text Components")]
|
||||
[SerializeField] TMP_Text m_SnapTurnText;
|
||||
[SerializeField] TMP_Text m_RoomCodeText;
|
||||
[SerializeField] TMP_Text m_TimeText;
|
||||
[SerializeField] TMP_Text[] m_RoomNameText;
|
||||
[SerializeField] TMP_InputField m_RoomNameInputField;
|
||||
[SerializeField] TMP_Text[] m_PlayerCountText;
|
||||
|
||||
[Header("Voice Chat")]
|
||||
[SerializeField] Button m_MicPermsButton;
|
||||
[SerializeField] Slider m_InputVolumeSlider;
|
||||
[SerializeField] Slider m_OutputVolumeSlider;
|
||||
[SerializeField] Image m_LocalPlayerAudioVolume;
|
||||
[SerializeField] Image m_MutedIcon;
|
||||
[SerializeField] Image m_MicOnIcon;
|
||||
[SerializeField] TMP_Text m_VoiceChatStatus;
|
||||
|
||||
[Header("Player Options")]
|
||||
[SerializeField] Vector2 m_MinMaxMoveSpeed = new Vector2(2.0f, 10.0f);
|
||||
[SerializeField] Vector2 m_MinMaxTurnAmount = new Vector2(15.0f, 180.0f);
|
||||
[SerializeField] float m_SnapTurnUpdateAmount = 15.0f;
|
||||
|
||||
VoiceChatManager m_VoiceChatManager;
|
||||
DynamicMoveProvider m_MoveProvider;
|
||||
SnapTurnProvider m_TurnProvider;
|
||||
UnityEngine.XR.Interaction.Toolkit.Locomotion.Comfort.TunnelingVignetteController m_TunnelingVignetteController;
|
||||
|
||||
PermissionCallbacks permCallbacks;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
m_VoiceChatManager = FindFirstObjectByType<VoiceChatManager>();
|
||||
m_MoveProvider = FindFirstObjectByType<DynamicMoveProvider>();
|
||||
m_TurnProvider = FindFirstObjectByType<SnapTurnProvider>();
|
||||
m_TunnelingVignetteController = FindFirstObjectByType<UnityEngine.XR.Interaction.Toolkit.Locomotion.Comfort.TunnelingVignetteController>();
|
||||
|
||||
XRINetworkGameManager.Connected.Subscribe(ConnectOnline);
|
||||
XRINetworkGameManager.ConnectedRoomName.Subscribe(UpdateRoomName);
|
||||
|
||||
m_VoiceChatManager.selfMuted.Subscribe(MutedChanged);
|
||||
m_VoiceChatManager.connectionStatus.Subscribe(UpdateVoiceChatStatus);
|
||||
m_InputVolumeSlider.onValueChanged.AddListener(SetInputVolume);
|
||||
m_OutputVolumeSlider.onValueChanged.AddListener(SetOutputVolume);
|
||||
|
||||
ConnectOnline(false);
|
||||
|
||||
if (m_ToggleMenuAction != null)
|
||||
m_ToggleMenuAction.action.performed += ctx => ToggleMenu();
|
||||
else
|
||||
Utils.Log("No toggle menu action assigned to OptionsPanel", 1);
|
||||
|
||||
permCallbacks = new PermissionCallbacks();
|
||||
permCallbacks.PermissionDenied += PermissionCallbacks_PermissionDenied;
|
||||
permCallbacks.PermissionGranted += PermissionCallbacks_PermissionGranted;
|
||||
}
|
||||
|
||||
internal void PermissionCallbacks_PermissionGranted(string permissionName)
|
||||
{
|
||||
Utils.Log($"{permissionName} PermissionCallbacks_PermissionGranted");
|
||||
m_MicPermsButton.gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
internal void PermissionCallbacks_PermissionDenied(string permissionName)
|
||||
{
|
||||
Utils.Log($"{permissionName} PermissionCallbacks_PermissionDenied");
|
||||
}
|
||||
|
||||
void OnEnable()
|
||||
{
|
||||
TogglePanel(0);
|
||||
|
||||
if (!Permission.HasUserAuthorizedPermission(Permission.Microphone))
|
||||
{
|
||||
m_MicPermsButton.gameObject.SetActive(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_MicPermsButton.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Unsubscribe(ConnectOnline);
|
||||
XRINetworkGameManager.ConnectedRoomName.Unsubscribe(UpdateRoomName);
|
||||
m_VoiceChatManager.selfMuted.Unsubscribe(MutedChanged);
|
||||
|
||||
m_VoiceChatManager.connectionStatus.Unsubscribe(UpdateVoiceChatStatus);
|
||||
m_InputVolumeSlider.onValueChanged.RemoveListener(SetInputVolume);
|
||||
m_OutputVolumeSlider.onValueChanged.RemoveListener(SetOutputVolume);
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
m_TimeText.text = $"{DateTime.Now:h:mm}<size=4><voffset=1em>{DateTime.Now:tt}</size></voffset>";
|
||||
if (XRINetworkGameManager.Connected.Value)
|
||||
{
|
||||
m_LocalPlayerAudioVolume.fillAmount = XRINetworkPlayer.LocalPlayer.playerVoiceAmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LocalPlayerAudioVolume.fillAmount = OfflinePlayerAvatar.voiceAmp.Value;
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectOnline(bool connected)
|
||||
{
|
||||
foreach (var go in m_OfflineWarningPanels)
|
||||
{
|
||||
go.SetActive(!connected);
|
||||
}
|
||||
|
||||
foreach (var go in m_OnlinePanels)
|
||||
{
|
||||
go.SetActive(connected);
|
||||
}
|
||||
|
||||
if (connected)
|
||||
{
|
||||
m_HostRoomPanel.SetActive(NetworkManager.Singleton.IsServer);
|
||||
m_ClientRoomPanel.SetActive(!NetworkManager.Singleton.IsServer);
|
||||
UpdateRoomName(XRINetworkGameManager.ConnectedRoomName.Value);
|
||||
m_MutedIcon.enabled = false;
|
||||
m_MicOnIcon.enabled = true;
|
||||
m_LocalPlayerAudioVolume.enabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleMenu(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void TogglePanel(int panelID)
|
||||
{
|
||||
for (int i = 0; i < m_Panels.Length; i++)
|
||||
{
|
||||
m_PanelToggles[i].SetIsOnWithoutNotify(panelID == i);
|
||||
m_Panels[i].SetActive(i == panelID);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Toggles the menu on or off.
|
||||
/// </summary>
|
||||
/// <param name="overrideToggle"></param>
|
||||
/// <param name="overrideValue"></param>
|
||||
public void ToggleMenu(bool overrideToggle = false, bool overrideValue = false)
|
||||
{
|
||||
if (overrideToggle)
|
||||
{
|
||||
gameObject.SetActive(overrideValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
ToggleMenu();
|
||||
}
|
||||
TogglePanel(0);
|
||||
}
|
||||
|
||||
public void ToggleMenu()
|
||||
{
|
||||
gameObject.SetActive(!gameObject.activeSelf);
|
||||
}
|
||||
|
||||
public void LogOut()
|
||||
{
|
||||
XRINetworkGameManager.Instance.Disconnect();
|
||||
}
|
||||
|
||||
public void QuickJoin()
|
||||
{
|
||||
XRINetworkGameManager.Instance.QuickJoinLobby();
|
||||
}
|
||||
|
||||
public void QuitGame()
|
||||
{
|
||||
#if UNITY_EDITOR
|
||||
EditorApplication.isPlaying = false;
|
||||
#else
|
||||
Application.Quit();
|
||||
#endif
|
||||
}
|
||||
|
||||
void UpdateVoiceChatStatus(string statusMessage)
|
||||
{
|
||||
m_VoiceChatStatus.text = $"<b>Voice Chat:</b> {statusMessage}";
|
||||
}
|
||||
public void SetVolumeLevel(float sliderValue)
|
||||
{
|
||||
m_Mixer.SetFloat("MainVolume", Mathf.Log10(sliderValue) * 20);
|
||||
}
|
||||
public void SetInputVolume(float volume)
|
||||
{
|
||||
float perc = Mathf.Lerp(-10, 10, volume);
|
||||
m_VoiceChatManager.SetInputVolume(perc);
|
||||
}
|
||||
|
||||
public void SetOutputVolume(float volume)
|
||||
{
|
||||
float perc = Mathf.Lerp(-10, 10, volume);
|
||||
m_VoiceChatManager.SetOutputVolume(perc);
|
||||
}
|
||||
|
||||
public void ToggleMute()
|
||||
{
|
||||
m_VoiceChatManager.ToggleSelfMute();
|
||||
}
|
||||
|
||||
void MutedChanged(bool muted)
|
||||
{
|
||||
m_MutedIcon.enabled = muted;
|
||||
m_MicOnIcon.enabled = !muted;
|
||||
m_LocalPlayerAudioVolume.enabled = !muted;
|
||||
PlayerHudNotification.Instance.ShowText($"<b>Microphone: {(muted ? "OFF" : "ON")}</b>");
|
||||
}
|
||||
|
||||
// Room Options
|
||||
public void UpdateRoomPrivacy(bool toggle)
|
||||
{
|
||||
XRINetworkGameManager.Instance.lobbyManager.UpdateRoomPrivacy(toggle);
|
||||
}
|
||||
|
||||
public void SubmitNewRoomName(string text)
|
||||
{
|
||||
XRINetworkGameManager.Instance.lobbyManager.UpdateLobbyName(text);
|
||||
}
|
||||
|
||||
void UpdateRoomName(string newValue)
|
||||
{
|
||||
m_RoomCodeText.text = $"Room Code: {XRINetworkGameManager.ConnectedRoomCode}";
|
||||
foreach (var t in m_RoomNameText)
|
||||
{
|
||||
t.text = XRINetworkGameManager.ConnectedRoomName.Value;
|
||||
}
|
||||
m_RoomNameInputField.text = XRINetworkGameManager.ConnectedRoomName.Value;
|
||||
}
|
||||
|
||||
// Player Options
|
||||
public void SetHandOrientation(bool toggle)
|
||||
{
|
||||
if (toggle)
|
||||
{
|
||||
m_MoveProvider.leftHandMovementDirection = DynamicMoveProvider.MovementDirection.HandRelative;
|
||||
}
|
||||
}
|
||||
public void SetHeadOrientation(bool toggle)
|
||||
{
|
||||
if (toggle)
|
||||
{
|
||||
m_MoveProvider.leftHandMovementDirection = DynamicMoveProvider.MovementDirection.HeadRelative;
|
||||
}
|
||||
}
|
||||
public void SetMoveSpeed(float speedPercent)
|
||||
{
|
||||
m_MoveProvider.moveSpeed = Mathf.Lerp(m_MinMaxMoveSpeed.x, m_MinMaxMoveSpeed.y, speedPercent);
|
||||
}
|
||||
|
||||
public void UpdateSnapTurn(int dir)
|
||||
{
|
||||
float newTurnAmount = Mathf.Clamp(m_TurnProvider.turnAmount + (m_SnapTurnUpdateAmount * dir), m_MinMaxTurnAmount.x, m_MinMaxTurnAmount.y);
|
||||
m_TurnProvider.turnAmount = newTurnAmount;
|
||||
m_SnapTurnText.text = $"{newTurnAmount}°";
|
||||
}
|
||||
|
||||
public void ToggleTunnelingVignette(bool toggle)
|
||||
{
|
||||
m_TunnelingVignetteController.gameObject.SetActive(toggle);
|
||||
}
|
||||
|
||||
public void ToggleFlight(bool toggle)
|
||||
{
|
||||
m_MoveProvider.useGravity = !toggle;
|
||||
m_MoveProvider.enableFly = toggle;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b0744eb7de4f61b44b11f87f9ab77757
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,36 @@
|
||||
using UnityEngine;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class PopoutUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] bool m_HideOnStart = false;
|
||||
[SerializeField] float m_DistanceFromFace = .25f;
|
||||
[SerializeField] float m_YOffset;
|
||||
Transform m_MainCamTransform;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (m_HideOnStart)
|
||||
gameObject.SetActive(false);
|
||||
}
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
if (m_MainCamTransform == null)
|
||||
{
|
||||
m_MainCamTransform = Camera.main.transform;
|
||||
}
|
||||
|
||||
transform.position = m_MainCamTransform.position;
|
||||
|
||||
Vector3 rot = m_MainCamTransform.eulerAngles;
|
||||
rot.x = 0;
|
||||
rot.z = 0;
|
||||
transform.rotation = Quaternion.Euler(rot);
|
||||
|
||||
transform.position += transform.forward * m_DistanceFromFace;
|
||||
transform.position += Vector3.up * -m_YOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c957e0303d5d94b4c83ea19b0d796e3b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
[RequireComponent(typeof(Toggle))]
|
||||
public class TooltipUI : MonoBehaviour
|
||||
{
|
||||
[SerializeField] GameObject m_TooltipObject;
|
||||
[SerializeField] bool m_StartShowing = false;
|
||||
Toggle m_Toggle;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
if (!TryGetComponent(out m_Toggle) || m_TooltipObject == null)
|
||||
{
|
||||
Utils.Log($"{gameObject.name} Missing Setup Requirements! Disabling Now.", 2);
|
||||
gameObject.SetActive(false);
|
||||
enabled = false;
|
||||
return;
|
||||
}
|
||||
m_Toggle.onValueChanged.AddListener(OnToggle);
|
||||
ResetTooltip();
|
||||
}
|
||||
|
||||
void OnDestroy()
|
||||
{
|
||||
m_Toggle.onValueChanged.RemoveListener(OnToggle);
|
||||
}
|
||||
|
||||
void OnToggle(bool toggle)
|
||||
{
|
||||
if (toggle)
|
||||
{
|
||||
ShowTooltip();
|
||||
}
|
||||
else
|
||||
{
|
||||
HideTooltip();
|
||||
}
|
||||
}
|
||||
|
||||
public void ShowTooltip()
|
||||
{
|
||||
m_TooltipObject.SetActive(true);
|
||||
}
|
||||
|
||||
public void HideTooltip()
|
||||
{
|
||||
if (m_Toggle.isOn) return;
|
||||
m_TooltipObject.SetActive(false);
|
||||
}
|
||||
|
||||
public void ResetTooltip()
|
||||
{
|
||||
m_Toggle.SetIsOnWithoutNotify(false);
|
||||
HideTooltip();
|
||||
if (m_StartShowing)
|
||||
{
|
||||
m_Toggle.isOn = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bad7a989d0f699646b486cecce6bd95e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,88 @@
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
|
||||
namespace XRMultiplayer
|
||||
{
|
||||
public class WorldCanvas : MonoBehaviour
|
||||
{
|
||||
[SerializeField] Transform m_PlayerNameTagsParent;
|
||||
[SerializeField] float m_nameTagOffsetHeight = 0.3f;
|
||||
readonly Dictionary<PlayerNameTag, XRINetworkPlayer> playerDictionary = new Dictionary<PlayerNameTag, XRINetworkPlayer>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Subscribe(OnConnectedUpdate);
|
||||
XRINetworkGameManager.Instance.playerStateChanged += ConnectedPlayerStateChange;
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
XRINetworkGameManager.Connected.Unsubscribe(OnConnectedUpdate);
|
||||
XRINetworkGameManager.Instance.playerStateChanged -= ConnectedPlayerStateChange;
|
||||
}
|
||||
|
||||
void OnConnectedUpdate(bool connected)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
foreach (var kvp in playerDictionary)
|
||||
{
|
||||
Destroy(kvp.Key.gameObject);
|
||||
}
|
||||
playerDictionary.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
void ConnectedPlayerStateChange(ulong playerId, bool connected)
|
||||
{
|
||||
if (!connected)
|
||||
{
|
||||
if (!RemovePlayerNameTag(playerId))
|
||||
{
|
||||
Utils.Log($"Failed to Remove Player with id {playerId}.", 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool RemovePlayerNameTag(ulong playerId)
|
||||
{
|
||||
foreach (var key in playerDictionary.Keys)
|
||||
{
|
||||
if (key.playerId == playerId)
|
||||
{
|
||||
playerDictionary.Remove(key);
|
||||
Destroy(key.gameObject);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void SetupPlayerNameTag(XRINetworkPlayer player, PlayerNameTag nameTag)
|
||||
{
|
||||
nameTag.SetupNameTag(player);
|
||||
nameTag.transform.SetParent(m_PlayerNameTagsParent);
|
||||
|
||||
if (!playerDictionary.ContainsKey(nameTag))
|
||||
{
|
||||
playerDictionary.Add(nameTag, player);
|
||||
}
|
||||
|
||||
if (player.IsLocalPlayer)
|
||||
{
|
||||
nameTag.gameObject.SetActive(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
foreach (var kvp in playerDictionary)
|
||||
{
|
||||
kvp.Key.transform.position = kvp.Value.head.position + Vector3.up * m_nameTagOffsetHeight;
|
||||
kvp.Key.UpdateVoice(kvp.Value.playerVoiceAmp);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12170d03a6fbce442bc18f83fcee080b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user