Added better GPS handling, Improved test mode, Fixed naming of players not being broadcast until a new HelloClient, Fixed lobby restarts, Fixed task handling

This commit is contained in:
Bandwidth
2026-04-27 23:18:13 +02:00
parent d886f97e14
commit 207f997254
8 changed files with 1175 additions and 77 deletions

View File

@@ -25,6 +25,8 @@ namespace Subsystems
private List<TaskEntry> _tasks = new List<TaskEntry>();
private bool _minigameOpen;
private string _loadedMinigameScene;
private Camera _hostCameraSuspended;
private GameObject _hostInGameHudHidden;
// Proximity state (checked every frame in UpdateProximity)
public GeoSus.Client.GameTask NearbyTask { get; private set; }
@@ -190,12 +192,31 @@ namespace Subsystems
// Inform server that task started
_gameClient.Send(new TaskStart { TaskId = entry.ServerTask.TaskId });
// Disable the host scene's main camera while the minigame is up.
// With both cameras enabled the minigame's UI/3D content would
// fight the host's map camera for screen space, and what gets
// drawn depends on Camera.depth which isn't guaranteed across
// scenes. Restored in FinishMinigame.
_hostCameraSuspended = Camera.main;
if (_hostCameraSuspended != null) _hostCameraSuspended.enabled = false;
// Hide the persistent InGame HUD canvas (if present). It lives
// in Client.unity and renders Screen Space - Overlay so it would
// otherwise stack on top of the minigame's UI regardless of
// which scene is active. SetActive(false) is reversible.
_hostInGameHudHidden = GameObject.Find("InGame");
if (_hostInGameHudHidden != null && _hostInGameHudHidden.activeSelf)
_hostInGameHudHidden.SetActive(false);
else
_hostInGameHudHidden = null; // nothing to restore
var op = SceneManager.LoadSceneAsync(entry.MinigameScene, LoadSceneMode.Additive);
if (op == null)
{
Debug.LogError($"[Tasks] LoadSceneAsync returned null for '{entry.MinigameScene}'.");
GameManager.Instance?.uiSubsystem?.ShowToast(
$"Task scene failed to load: {entry.MinigameScene}");
if (_hostCameraSuspended != null) { _hostCameraSuspended.enabled = true; _hostCameraSuspended = null; }
_minigameOpen = false;
yield break;
}
@@ -203,8 +224,34 @@ namespace Subsystems
_loadedMinigameScene = entry.MinigameScene;
// Find the ITask component in the newly loaded scene
// CRITICAL: switch the active scene to the loaded minigame.
// LoadSceneMode.Additive stacks scenes without changing which one
// is "active" - and an inactive scene's RenderSettings, ambient
// light, and skybox don't drive rendering. The host (Client.unity)
// remains active and its lighting context still applies, which
// is the root cause of "task opens to white screen": the
// minigame's content loads but its visuals don't take over.
// Without SetActiveScene, even minigames that ARE wired up
// correctly render against the host's lighting and look broken.
Scene scene = SceneManager.GetSceneByName(entry.MinigameScene);
if (scene.IsValid()) SceneManager.SetActiveScene(scene);
// Diagnostic: count cameras / canvases / lights in the loaded
// scene. If the white screen persists after this fix, the
// numbers tell us whether the scene is missing rendering bits
// (camera=0, canvas=0) or if the issue is elsewhere.
int camCount = 0, canvasCount = 0, lightCount = 0;
foreach (var root in scene.GetRootGameObjects())
{
camCount += root.GetComponentsInChildren<Camera>(true).Length;
canvasCount += root.GetComponentsInChildren<Canvas>(true).Length;
lightCount += root.GetComponentsInChildren<Light>(true).Length;
}
Debug.Log($"[Tasks] Loaded '{entry.MinigameScene}': cameras={camCount}, " +
$"canvases={canvasCount}, lights={lightCount}, " +
$"activeScene={SceneManager.GetActiveScene().name}");
// Find the ITask component in the newly loaded scene
ITask taskComponent = null;
foreach (var root in scene.GetRootGameObjects())
{
@@ -214,7 +261,9 @@ namespace Subsystems
if (taskComponent == null)
{
Debug.LogWarning($"[Tasks] No ITask found in '{entry.MinigameScene}'. Auto-completing.");
Debug.LogWarning($"[Tasks] No ITask found in '{entry.MinigameScene}'. " +
$"Either the minigame's controller script isn't attached to a GameObject in the scene, " +
$"or the script doesn't implement ITask. Auto-completing.");
yield return FinishMinigame(entry, true);
yield break;
}
@@ -246,14 +295,33 @@ namespace Subsystems
Debug.Log($"[Tasks] Task '{entry.ServerTask.Name}' exited without completion.");
}
// Unload minigame scene
// Unload minigame scene. Switch the active scene back to the
// host BEFORE the unload so we don't end up with no active
// scene mid-frame (Unity will complain and lighting flickers).
if (!string.IsNullOrEmpty(_loadedMinigameScene))
{
var hostScene = SceneManager.GetSceneByName("Client");
if (hostScene.IsValid()) SceneManager.SetActiveScene(hostScene);
var unload = SceneManager.UnloadSceneAsync(_loadedMinigameScene);
yield return unload;
_loadedMinigameScene = null;
}
// Re-enable the host camera that was suspended during the minigame.
if (_hostCameraSuspended != null)
{
_hostCameraSuspended.enabled = true;
_hostCameraSuspended = null;
}
// Re-show the InGame HUD canvas hidden at minigame entry.
if (_hostInGameHudHidden != null)
{
_hostInGameHudHidden.SetActive(true);
_hostInGameHudHidden = null;
}
_minigameOpen = false;
}
}