Make the number of hunters configurable in MatchManager
StartMatch rolled exactly one random Hunter. Add a serialized hunterCount field (default 1, [Min(0)], inspector-tunable) and roll N distinct random Hunters via a partial Fisher-Yates on the client-id list, clamped to the player count: 0 = all Hiders, >= player count = all Hunters. The match sequence now carries a HashSet of hunter ids instead of a single id. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
1 parent
346a0c6e8c
commit
0834419a56
1 file changed
+27
-7
@@ -29,8 +29,9 @@ using UnityEngine.SceneManagement;
|
||||
///
|
||||
/// Flow: server start -> additive sync mode set -> Lobby loaded additively -> Player spawned for every
|
||||
/// connected peer (full mode set, including First Person). Late joiners spawn on connect into the
|
||||
/// already-loaded scene. The host walks into the Start Match trigger -> <see cref="StartMatch"/>: one
|
||||
/// random connected client is rolled Hunter, the rest Hider; the Lobby is unloaded and Test Map loaded
|
||||
/// already-loaded scene. The host walks into the Start Match trigger -> <see cref="StartMatch"/>: a
|
||||
/// configurable number of random connected clients are rolled Hunter (<see cref="hunterCount"/>,
|
||||
/// default 1), the rest Hider; the Lobby is unloaded and Test Map loaded
|
||||
/// (strictly serialized - an NGO constraint, only one scene op in flight); then every player object is
|
||||
/// despawned and respawned as its role's prefab variant.
|
||||
///
|
||||
@@ -81,6 +82,12 @@ public class MatchManager : MonoBehaviour
|
||||
"free-cam rig is a separate scene object. Must be a registered network prefab.")]
|
||||
[SerializeField] private GameObject spectatorPrefab;
|
||||
|
||||
[Header("Roles")]
|
||||
[Tooltip("How many randomly chosen players become Hunters at match start; everyone else is a Hider. " +
|
||||
"0 = all Hiders; a value at or above the player count makes everyone a Hunter. Default 1.")]
|
||||
[Min(0)]
|
||||
[SerializeField] private int hunterCount = 1;
|
||||
|
||||
[Header("Spawn")]
|
||||
[Tooltip("World position lobby avatars are spawned at (raised a touch above the floor so gravity " +
|
||||
"settles them). Per-client ring fan-out is applied on top (NetworkPlayerSetup.PlaceOnSpawnRing).")]
|
||||
@@ -351,13 +358,26 @@ public class MatchManager : MonoBehaviour
|
||||
if (ids.Count == 0) return;
|
||||
|
||||
Phase = MatchPhase.Transitioning;
|
||||
ulong hunterId = ids[_roleRng.Next(ids.Count)];
|
||||
Debug.Log($"[MatchManager] Starting match. Hunter = client {hunterId}, {ids.Count} player(s).", this);
|
||||
|
||||
StartCoroutine(MatchSequence(hunterId));
|
||||
// Roll N distinct random Hunters (clamped to the player count); everyone else is a Hider.
|
||||
// hunterCount 0 -> all Hiders, >= player count -> all Hunters. Partial Fisher-Yates: swap a
|
||||
// random not-yet-picked id into each leading slot, then take that slot as a Hunter.
|
||||
int wanted = Mathf.Clamp(hunterCount, 0, ids.Count);
|
||||
var hunterIds = new HashSet<ulong>();
|
||||
for (int i = 0; i < wanted; i++)
|
||||
{
|
||||
int j = i + _roleRng.Next(ids.Count - i);
|
||||
(ids[i], ids[j]) = (ids[j], ids[i]);
|
||||
hunterIds.Add(ids[i]);
|
||||
}
|
||||
|
||||
Debug.Log($"[MatchManager] Starting match. {hunterIds.Count} hunter(s), " +
|
||||
$"{ids.Count - hunterIds.Count} hider(s), {ids.Count} player(s).", this);
|
||||
|
||||
StartCoroutine(MatchSequence(hunterIds));
|
||||
}
|
||||
|
||||
private IEnumerator MatchSequence(ulong hunterId)
|
||||
private IEnumerator MatchSequence(HashSet<ulong> hunterIds)
|
||||
{
|
||||
var sm = _net.SceneManager;
|
||||
|
||||
@@ -371,7 +391,7 @@ public class MatchManager : MonoBehaviour
|
||||
SceneEventType.LoadEventCompleted, matchSceneName);
|
||||
|
||||
// 3. Respawn every player as its rolled role's prefab variant.
|
||||
RespawnAll(id => (id == hunterId) ? hunterPrefab : hiderPrefab, matchSpawnCenter);
|
||||
RespawnAll(id => hunterIds.Contains(id) ? hunterPrefab : hiderPrefab, matchSpawnCenter);
|
||||
|
||||
Phase = MatchPhase.InMatch;
|
||||
Debug.Log("[MatchManager] Match started.", this);
|
||||
|
||||
Reference in new issue
Block a user