Fix player components injection. Add lobby reloading when clients change
This commit is contained in:
@@ -6,4 +6,5 @@ public struct PlayerInfo
|
||||
{
|
||||
public string Name;
|
||||
public Sprite Image;
|
||||
public bool isLocalPlayer;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@ using UnityEngine;
|
||||
using Zenject;
|
||||
using ParrelSync;
|
||||
using UnityEngine.Events;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class GameManager : NetworkBehaviour
|
||||
{
|
||||
@@ -27,10 +28,13 @@ public class GameManager : NetworkBehaviour
|
||||
[SerializeField]
|
||||
private bool autoConnectOrHost = true;
|
||||
|
||||
public bool IsMultiplayer => networkManager.IsHost || networkManager.IsClient;
|
||||
public bool IsMultiplayer => networkManager.IsConnectedClient;
|
||||
|
||||
public NetworkClient LocalClient => networkManager.LocalClient;
|
||||
|
||||
public UnityEvent OnConnected;
|
||||
public UnityEvent OnDisconnected;
|
||||
public UnityEvent<IReadOnlyList<NetworkClient>> OnClientsChanged;
|
||||
|
||||
private void Start()
|
||||
{
|
||||
@@ -78,11 +82,13 @@ public class GameManager : NetworkBehaviour
|
||||
private void OnClientStarted()
|
||||
{
|
||||
OnConnected?.Invoke();
|
||||
OnClientsChanged.Invoke(networkManager.ConnectedClientsList);
|
||||
}
|
||||
|
||||
private void OnClientStopped(bool wasHost)
|
||||
{
|
||||
OnDisconnected?.Invoke();
|
||||
OnClientsChanged.Invoke(networkManager.ConnectedClientsList);
|
||||
}
|
||||
|
||||
private void OnClientConnectedCallback(ulong clientId)
|
||||
@@ -93,6 +99,8 @@ public class GameManager : NetworkBehaviour
|
||||
{
|
||||
StartCoroutine(SwitchSoloMultiplayerRig(false));
|
||||
}
|
||||
|
||||
OnClientsChanged.Invoke(networkManager.ConnectedClientsList);
|
||||
}
|
||||
|
||||
private IEnumerator SwitchSoloMultiplayerRig(bool toSolo)
|
||||
@@ -126,5 +134,7 @@ public class GameManager : NetworkBehaviour
|
||||
{
|
||||
StartCoroutine(SwitchSoloMultiplayerRig(true));
|
||||
}
|
||||
|
||||
OnClientsChanged.Invoke(networkManager.ConnectedClientsList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,13 @@
|
||||
using HurricaneVR.Framework.ControllerInput;
|
||||
using HurricaneVR.Framework.Core.UI;
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using Zenject;
|
||||
|
||||
public class HandMenuUI : MonoBehaviour
|
||||
public class HandMenuUI : NetworkBehaviour
|
||||
{
|
||||
[Inject]
|
||||
[ReadOnly]
|
||||
@@ -89,6 +88,14 @@ public class HandMenuUI : MonoBehaviour
|
||||
settingsButton.onClick.AddListener(() => SettingsClicked());
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
base.OnNetworkSpawn();
|
||||
|
||||
// Player components need to be injected manualy again, because NetworkManager doesn't inject them.
|
||||
gameObject.Inject();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
CheckInput();
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using HurricaneVR.Framework.Core.UI;
|
||||
using Sirenix.OdinInspector;
|
||||
using System.Collections.Generic;
|
||||
using TMPro;
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
@@ -51,6 +52,8 @@ public class LobbyMenuUI : MonoBehaviour
|
||||
|
||||
private bool isConnected => gameManager.IsMultiplayer;
|
||||
|
||||
private IReadOnlyList<NetworkClient> networkClients = new List<NetworkClient>();
|
||||
|
||||
private void Start()
|
||||
{
|
||||
if (uiInput == null) return;
|
||||
@@ -64,6 +67,12 @@ public class LobbyMenuUI : MonoBehaviour
|
||||
gameManager.OnConnected.AddListener(() => UpdateUI());
|
||||
gameManager.OnDisconnected.AddListener(() => UpdateUI());
|
||||
|
||||
gameManager.OnClientsChanged.AddListener((clients) =>
|
||||
{
|
||||
networkClients = clients;
|
||||
UpdateUI();
|
||||
});
|
||||
|
||||
UpdateUI();
|
||||
}
|
||||
|
||||
@@ -73,6 +82,28 @@ public class LobbyMenuUI : MonoBehaviour
|
||||
connected.SetActive(isConnected);
|
||||
joinButton.interactable = true;
|
||||
hostButton.interactable = true;
|
||||
|
||||
for (int i = 0; i < playerItems.Length; i++)
|
||||
{
|
||||
var item = playerItems[i];
|
||||
|
||||
if (i > networkClients.Count -1)
|
||||
{
|
||||
item.Setup(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
var client = networkClients[i];
|
||||
|
||||
var playerInfo = new PlayerInfo()
|
||||
{
|
||||
Name = client.ClientId.ToString(),
|
||||
isLocalPlayer = client.ClientId == gameManager.LocalClient.ClientId
|
||||
};
|
||||
|
||||
item.Setup(playerInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void JoinClicked()
|
||||
|
||||
@@ -23,6 +23,9 @@ public class PlayerItemUI : MonoBehaviour
|
||||
[SerializeField]
|
||||
private PlayerInfo? playerInfo;
|
||||
|
||||
[SerializeField]
|
||||
private Sprite defaultPlayerImage;
|
||||
|
||||
bool isEmpty => playerInfo == null;
|
||||
|
||||
private void Start()
|
||||
@@ -44,7 +47,7 @@ public class PlayerItemUI : MonoBehaviour
|
||||
if (!isEmpty)
|
||||
{
|
||||
nameText.text = playerInfo?.Name;
|
||||
playerImage.sprite = playerInfo?.Image;
|
||||
playerImage.sprite = playerInfo?.Image ?? defaultPlayerImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
46
Assets/Scripts/Utils/Injector.cs
Normal file
46
Assets/Scripts/Utils/Injector.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using static Zenject.ZenAutoInjecter;
|
||||
using Zenject;
|
||||
using ModestTree;
|
||||
|
||||
public static class Injector
|
||||
{
|
||||
static DiContainer LookupContainer(GameObject go, ContainerSources container)
|
||||
{
|
||||
if (container == ContainerSources.ProjectContext)
|
||||
{
|
||||
return ProjectContext.Instance.Container;
|
||||
}
|
||||
|
||||
if (container == ContainerSources.SceneContext)
|
||||
{
|
||||
return GetContainerForCurrentScene(go);
|
||||
}
|
||||
|
||||
Assert.IsEqual(container, ContainerSources.SearchHierarchy);
|
||||
|
||||
var parentContext = go.transform.GetComponentInParent<Context>();
|
||||
|
||||
if (parentContext != null)
|
||||
{
|
||||
return parentContext.Container;
|
||||
}
|
||||
|
||||
return GetContainerForCurrentScene(go);
|
||||
}
|
||||
|
||||
static DiContainer GetContainerForCurrentScene(GameObject go)
|
||||
{
|
||||
return ProjectContext.Instance.Container
|
||||
.Resolve<SceneContextRegistry>()
|
||||
.GetContainerForScene(go.scene);
|
||||
}
|
||||
|
||||
public static void Inject(this GameObject go, ContainerSources container = ContainerSources.SceneContext)
|
||||
{
|
||||
LookupContainer(go, container).InjectGameObject(go);
|
||||
}
|
||||
}
|
||||
11
Assets/Scripts/Utils/Injector.cs.meta
Normal file
11
Assets/Scripts/Utils/Injector.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b7eb2cd65a9697441890fa5f41706bf7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
Reference in New Issue
Block a user