online game working

This commit is contained in:
2025-10-05 19:24:52 +02:00
parent 7cec95b8a0
commit dd89012919
3 changed files with 77 additions and 11 deletions

View File

@@ -94,6 +94,8 @@ namespace MegaKoop.Game.Networking
IsLocal = true IsLocal = true
}); });
} }
pendingPlayers.Sort((a, b) => string.CompareOrdinal(a.SteamId ?? string.Empty, b.SteamId ?? string.Empty));
} }
private void HandleSceneLoaded(Scene scene, LoadSceneMode mode) private void HandleSceneLoaded(Scene scene, LoadSceneMode mode)
@@ -147,7 +149,7 @@ namespace MegaKoop.Game.Networking
var clone = Instantiate(template, spawnPosition, baseRotation, parent); var clone = Instantiate(template, spawnPosition, baseRotation, parent);
clone.name = BuildPlayerName(info, i); clone.name = BuildPlayerName(info, i);
ConfigureCloneForPlayer(clone, info); ConfigureCloneForPlayer(clone, info, i);
clone.SetActive(true); clone.SetActive(true);
} }
@@ -184,13 +186,17 @@ namespace MegaKoop.Game.Networking
return center + offset; return center + offset;
} }
private void ConfigureCloneForPlayer(GameObject clone, LobbyPlayerInfo info) private void ConfigureCloneForPlayer(GameObject clone, LobbyPlayerInfo info, int index)
{ {
var controller = clone.GetComponent<ThirdPersonCharacterController>(); // Ensure network identity is deterministic across clients.
if (controller != null) var identity = clone.GetComponent<NetworkIdentity>() ?? clone.AddComponent<NetworkIdentity>();
{ identity.SetNetworkId(index + 1);
controller.enabled = info.IsLocal;
} var bridge = clone.GetComponent<SteamCharacterNetworkBridge>() ?? clone.AddComponent<SteamCharacterNetworkBridge>();
bridge.AssignOwner(ParseSteamId(info.SteamId), info.IsLocal);
var inputSender = clone.GetComponent<SteamLocalInputSender>() ?? clone.AddComponent<SteamLocalInputSender>();
inputSender.enabled = info.IsLocal;
// Local player keeps the camera and audio; remote avatars are visual only. // Local player keeps the camera and audio; remote avatars are visual only.
var cameras = clone.GetComponentsInChildren<Camera>(true); var cameras = clone.GetComponentsInChildren<Camera>(true);
@@ -217,11 +223,8 @@ namespace MegaKoop.Game.Networking
if (thirdPersonCamera != null) if (thirdPersonCamera != null)
{ {
thirdPersonCamera.enabled = info.IsLocal; thirdPersonCamera.enabled = info.IsLocal;
if (info.IsLocal)
{
thirdPersonCamera.SetTarget(clone.transform);
}
} }
} }
private static string BuildPlayerName(LobbyPlayerInfo info, int index) private static string BuildPlayerName(LobbyPlayerInfo info, int index)
@@ -241,6 +244,21 @@ namespace MegaKoop.Game.Networking
return "You"; return "You";
} }
private static ulong ParseSteamId(string steamId)
{
if (string.IsNullOrEmpty(steamId))
{
return 0;
}
if (ulong.TryParse(steamId, out var value))
{
return value;
}
return 0;
}
[Serializable] [Serializable]
private struct LobbyPlayerInfo private struct LobbyPlayerInfo
{ {

View File

@@ -49,5 +49,30 @@ namespace MegaKoop.Game.Networking
} }
public static bool TryGet(int id, out NetworkIdentity identity) => registry.TryGetValue(id, out identity); public static bool TryGet(int id, out NetworkIdentity identity) => registry.TryGetValue(id, out identity);
/// <summary>
/// Allows deterministic assignment so IDs match across clients.
/// </summary>
public void SetNetworkId(int id)
{
if (id == 0)
{
Debug.LogWarning("[NetworkIdentity] Cannot assign network id 0.");
return;
}
if (networkId == id)
{
return;
}
if (registry.TryGetValue(networkId, out NetworkIdentity existing) && existing == this)
{
registry.Remove(networkId);
}
networkId = id;
Register();
}
} }
} }

View File

@@ -366,7 +366,30 @@ namespace MegaKoop.UI
servicesRoot.AddComponent<SteamManager>(); servicesRoot.AddComponent<SteamManager>();
} }
T EnsureComponent<T>() where T : Component
{
if (servicesRoot.TryGetComponent<T>(out var existing))
{
return existing;
}
#if UNITY_2023_1_OR_NEWER
var found = Object.FindFirstObjectByType<T>(FindObjectsInactive.Include);
#else
var found = Object.FindObjectOfType<T>();
#endif
if (found != null)
{
return found;
}
return servicesRoot.AddComponent<T>();
}
EnsureComponent<SteamLobbyManager>();
EnsureComponent<SteamP2PTransport>();
EnsureComponent<SteamCoopNetworkManager>();
lobbyGameCoordinator = servicesRoot.GetComponent<LobbyGameSceneCoordinator>() ?? servicesRoot.AddComponent<LobbyGameSceneCoordinator>(); lobbyGameCoordinator = servicesRoot.GetComponent<LobbyGameSceneCoordinator>() ?? servicesRoot.AddComponent<LobbyGameSceneCoordinator>();
DontDestroyOnLoad(servicesRoot);
} }
} }