Reimplement solo and mp rig switching

This commit is contained in:
2024-09-12 16:55:54 +02:00
parent e428d3a9f9
commit f8822831aa
9 changed files with 119 additions and 198 deletions

View File

@@ -11,9 +11,14 @@ using Unity.Netcode.Components;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Rendering.Universal;
using Zenject;
public class PlayerComponent : NetworkBehaviour
{
[SerializeField]
[Inject]
private HVRInputModule inputModule;
[SerializeField]
private NetworkObject networkObject;
@@ -45,46 +50,61 @@ public class PlayerComponent : NetworkBehaviour
public Vector3 Rotation => controller.Camera.forward;
private bool isSoloRig => !networkObject.IsPlayerObject;
private bool isMultiplayerLocalRig => networkObject.IsLocalPlayer;
private bool isLocalRig => networkObject.IsLocalPlayer;
private bool isMultiplayerRemoteRig => !networkObject.IsOwner && networkObject.IsPlayerObject;
private bool isRemoteRig => !networkObject.IsOwner && networkObject.IsPlayerObject;
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
// Teleport information after player is loaded into scene
private Vector3 teleportPosition;
private Vector3 teleportRotation;
private bool teleportAfterLoad;
if (!isSoloRig)
{
name = $"Player - {networkObject.OwnerClientId}"
+ (networkObject.IsLocalPlayer ? " (local)" : "");
}
if (isMultiplayerRemoteRig)
{
StartCoroutine(DestroyMultiplayerComponents());
}
}
private bool isLoaded;
private void Start()
{
this.Inject();
StartCoroutine(AddDontDestroyToDependencies());
if (isSoloRig || isMultiplayerLocalRig)
if (isSoloRig)
{
foreach (var pointer in GetComponentsInChildren<HVRUIPointer>())
{
HVRInputModule.Instance.AddPointer(pointer);
}
AddPointersToInputModule();
name = "Player - SP";
StartCoroutine(DestroyComponentsNotNeededForSolo());
DontDestroyOnLoad(gameObject);
}
else if (isLocalRig)
{
AddPointersToInputModule();
name = $"Player - MP {networkObject.OwnerClientId} (local)";
}
else if (isRemoteRig)
{
name = $"Player - MP {networkObject.OwnerClientId}";
StartCoroutine(DestroyComponentsNotNeededForRemoteRigs());
}
if (!isSoloRig) return;
isLoaded = true;
audioListener.enabled = true;
StartCoroutine(DestroySoloComponents());
DontDestroyOnLoad(gameObject);
if (teleportAfterLoad)
{
Teleport(teleportPosition, teleportRotation);
}
}
private IEnumerator DestroyMultiplayerComponents()
private void AddPointersToInputModule()
{
foreach (var pointer in GetComponentsInChildren<HVRUIPointer>())
{
inputModule.AddPointer(pointer);
}
}
private IEnumerator DestroyComponentsNotNeededForRemoteRigs()
{
yield return new WaitForEndOfFrame();
@@ -105,7 +125,7 @@ public class PlayerComponent : NetworkBehaviour
controller.RemoveMultiplayerComponents();
}
private IEnumerator DestroySoloComponents()
private IEnumerator DestroyComponentsNotNeededForSolo()
{
yield return new WaitForEndOfFrame();
@@ -140,26 +160,18 @@ public class PlayerComponent : NetworkBehaviour
}
}
public void ToggleAudioListener(bool enabled) => audioListener.enabled = enabled;
public void Toggle(bool active)
{
// Only toggle solo rig components, not multiplayer one
if (networkObject == null || isSoloRig)
{
foreach (var d in dependencies)
{
d.SetActive(active);
}
audioListener.enabled = active;
gameObject.SetActive(active);
}
}
public void Teleport(Vector3 position, Vector3 direction)
{
teleporter.Teleport(position, direction);
if (isLoaded)
{
teleporter.Teleport(position, direction);
}
else
{
teleportPosition = position;
teleportRotation = direction;
teleportAfterLoad = true;
}
}
public void FadeScreen(float to, float duration)

View File

@@ -24,9 +24,6 @@ public class GlobalInstaller : MonoInstaller
[SerializeField]
private GameObject gameManagerPrefab;
[SerializeField]
private GameObject playerPrefab;
[SerializeField]
private GameObject uiManagerPrefab;
@@ -81,13 +78,6 @@ public class GlobalInstaller : MonoInstaller
Container.BindInstance(networkManager)
.AsSingle();
var playerGO = Instantiate(playerPrefab);
playerGO.name = playerPrefab.name;
var playerComponent = playerGO.GetComponent<PlayerComponent>();
Container.BindInstance(playerComponent)
.AsSingle();
Container.Bind<HVRInputModule>()
.FromComponentInNewPrefab(uiManagerPrefab)
.AsSingle()

View File

@@ -10,15 +10,13 @@ using System.Collections.Generic;
public class GameManager : NetworkBehaviour
{
[SerializeField]
[ReadOnly]
[Inject]
private PlayerComponent soloRig;
private GameObject rigPrefab;
[SerializeField]
[ReadOnly]
private PlayerComponent multiplayerRig;
private PlayerComponent player;
public PlayerComponent LocalPlayer => multiplayerRig ?? soloRig;
public PlayerComponent LocalPlayer => player;
[SerializeField]
[ReadOnly]
@@ -43,6 +41,8 @@ public class GameManager : NetworkBehaviour
networkManager.OnClientConnectedCallback += OnClientConnectedCallback;
networkManager.OnClientDisconnectCallback += OnClientDisconnectCallback;
player = SpawnSoloRig();
if (autoConnectOrHost)
{
if (ClonesManager.IsClone())
@@ -56,6 +56,11 @@ public class GameManager : NetworkBehaviour
}
}
private PlayerComponent SpawnSoloRig()
{
return Instantiate(rigPrefab).GetComponent<PlayerComponent>();
}
public void JoinGame(string code)
{
networkManager.StartClient();
@@ -107,23 +112,25 @@ public class GameManager : NetworkBehaviour
{
yield return new WaitForEndOfFrame();
var position = player.Position;
var rotation = player.Rotation;
player.DestroyDependencies();
if (toSolo)
{
soloRig.Toggle(toSolo);
soloRig.Teleport(multiplayerRig.Position, multiplayerRig.Rotation);
multiplayerRig.DestroyDependencies();
multiplayerRig = null;
yield return new WaitForEndOfFrame();
player = SpawnSoloRig();
}
else
{
soloRig.Toggle(toSolo);
Destroy(player.gameObject);
yield return new WaitForEndOfFrame();
var playerObject = networkManager.LocalClient.PlayerObject;
multiplayerRig = playerObject.GetComponent<PlayerComponent>();
multiplayerRig.Teleport(soloRig.Position, soloRig.Rotation);
multiplayerRig.ToggleAudioListener(true);
player = playerObject.GetComponent<PlayerComponent>();
}
player.Teleport(position, rotation);
}
private void OnClientDisconnectCallback(ulong clientId)

View File

@@ -70,6 +70,8 @@ public class HandMenuUI : NetworkBehaviour
private void Start()
{
this.Inject();
if (uiInput == null) return;
canvas = GetComponent<Canvas>();
@@ -88,14 +90,6 @@ public class HandMenuUI : NetworkBehaviour
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();

View File

@@ -43,4 +43,9 @@ public static class Injector
{
LookupContainer(go, container).InjectGameObject(go);
}
public static void Inject(this MonoBehaviour mb, ContainerSources container = ContainerSources.SceneContext)
{
LookupContainer(mb.gameObject, container).Inject(mb);
}
}