Bug Fixes
This commit is contained in:
@@ -38,6 +38,10 @@ public class RoundManager : NetworkBehaviour
|
||||
|
||||
private List<PlayerHealth> alivePlayers = new List<PlayerHealth>();
|
||||
|
||||
// Точки спавна, назначенные игрокам в этом раунде (параллельно alivePlayers).
|
||||
// Нужны, чтобы дождаться, пока серверная позиция догонит телепорт, перед стартом записи.
|
||||
private List<Vector3> spawnAssignments = new List<Vector3>();
|
||||
|
||||
private NetworkList<PlayerScore> playerScores = new NetworkList<PlayerScore>();
|
||||
|
||||
// pitDefenders[i] = ClientId игрока, которому принадлежит яма с pitIndex == i
|
||||
@@ -97,8 +101,13 @@ public class RoundManager : NetworkBehaviour
|
||||
|
||||
// Своя яма — не считается, побеждают только за попадание в ЧУЖУЮ яму.
|
||||
// Для клона сюда приходит ClientId его ОРИГИНАЛА (см. PitZone) — правило работает так же.
|
||||
if (_enteringClientId == pitDefenders[_pitIndex]) return;
|
||||
if (_enteringClientId == pitDefenders[_pitIndex])
|
||||
{
|
||||
Debug.Log($"[ROUND] pit{_pitIndex} own pit by {_enteringClientId} — no score");
|
||||
return;
|
||||
}
|
||||
|
||||
Debug.Log($"[ROUND] WIN pit{_pitIndex} by client={_enteringClientId} (defender={pitDefenders[_pitIndex]}) round={currentRound.Value} timeLeft={roundTimeRemaining.Value:F1}");
|
||||
AddScore(_enteringClientId);
|
||||
StartCoroutine(EndRound(_enteringClientId));
|
||||
}
|
||||
@@ -177,6 +186,7 @@ public class RoundManager : NetworkBehaviour
|
||||
|
||||
private IEnumerator EndRound(ulong _winnerClientId)
|
||||
{
|
||||
Debug.Log($"[ROUND] EndRound round={currentRound.Value} winner={_winnerClientId} timeLeft={roundTimeRemaining.Value:F1}");
|
||||
isRoundActive.Value = false;
|
||||
|
||||
// Сразу: стоп клонов + запись раунда в архив.
|
||||
@@ -219,6 +229,7 @@ public class RoundManager : NetworkBehaviour
|
||||
_players.Sort((_a, _b) => _a.OwnerClientId.CompareTo(_b.OwnerClientId));
|
||||
|
||||
alivePlayers.Clear();
|
||||
spawnAssignments.Clear();
|
||||
|
||||
// Одна яма на игрока: игрок с индексом _q защищает яму pitIndex == _q
|
||||
pitDefenders = new ulong[_players.Count];
|
||||
@@ -231,12 +242,59 @@ public class RoundManager : NetworkBehaviour
|
||||
pitDefenders[_q] = _clientId;
|
||||
|
||||
Vector3 _spawnPosition = spawnPoints[_q % spawnPoints.Length].position;
|
||||
|
||||
// Диагностика: спавн-поинт не должен быть внутри триггера ямы,
|
||||
// иначе клон заспавнится в яме и мгновенно "победит".
|
||||
Collider[] _overlaps = Physics.OverlapSphere(_spawnPosition, 0.5f, ~0, QueryTriggerInteraction.Collide);
|
||||
foreach (Collider _c in _overlaps)
|
||||
if (_c.GetComponentInParent<PitZone>() != null)
|
||||
Debug.LogError($"[ROUND] SPAWN {_q} at {_spawnPosition} INSIDE PIT '{_c.name}' для client={_clientId} — это причина мгновенной победы клона!");
|
||||
|
||||
_players[_q].Respawn(_spawnPosition);
|
||||
|
||||
alivePlayers.Add(_players[_q]);
|
||||
spawnAssignments.Add(_spawnPosition);
|
||||
}
|
||||
}
|
||||
|
||||
// Ждём, пока серверная позиция каждого игрока догонит телепорт на спавн.
|
||||
// Иначе первый сэмпл записи (positions[0]) окажется там, где игрок умер (в яме),
|
||||
// и клон следующего раунда заспавнится прямо в яме → мгновенная ложная победа.
|
||||
private IEnumerator WaitForPlayersAtSpawn()
|
||||
{
|
||||
float _timeout = Time.time + 3f;
|
||||
float _start = Time.time;
|
||||
|
||||
while (Time.time < _timeout)
|
||||
{
|
||||
bool _allAtSpawn = true;
|
||||
|
||||
for (int _i = 0; _i < alivePlayers.Count; _i++)
|
||||
{
|
||||
if (alivePlayers[_i] == null) continue;
|
||||
|
||||
float _dist = Vector3.Distance(alivePlayers[_i].transform.position, spawnAssignments[_i]);
|
||||
if (_dist > 1.5f)
|
||||
{
|
||||
_allAtSpawn = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_allAtSpawn)
|
||||
{
|
||||
Debug.Log($"[ROUND] players at spawn after {Time.time - _start:F2}s");
|
||||
yield break;
|
||||
}
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Debug.LogWarning($"[ROUND] WaitForPlayersAtSpawn TIMEOUT after 3s — positions may still be stale:");
|
||||
for (int _i = 0; _i < alivePlayers.Count; _i++)
|
||||
if (alivePlayers[_i] != null)
|
||||
Debug.LogWarning($"[ROUND] player {alivePlayers[_i].OwnerClientId} pos={alivePlayers[_i].transform.position} target={spawnAssignments[_i]} dist={Vector3.Distance(alivePlayers[_i].transform.position, spawnAssignments[_i]):F2}");
|
||||
}
|
||||
|
||||
private IEnumerator StartRoundWithDelay()
|
||||
{
|
||||
yield return new WaitForSeconds(1f);
|
||||
@@ -245,6 +303,10 @@ public class RoundManager : NetworkBehaviour
|
||||
|
||||
RespawnAllPlayers();
|
||||
|
||||
// КРИТИЧНО: ждём, пока серверная позиция игроков реально станет спавном,
|
||||
// прежде чем начинать запись — иначе клоны будут спавниться в яме (см. WaitForPlayersAtSpawn).
|
||||
yield return WaitForPlayersAtSpawn();
|
||||
|
||||
// Спавним клонов прошлых раундов и включаем запись у живых игроков
|
||||
if (GhostRoundManager.Current != null)
|
||||
GhostRoundManager.Current.ServerStartRound();
|
||||
@@ -252,6 +314,7 @@ public class RoundManager : NetworkBehaviour
|
||||
roundTimeRemaining.Value = roundDuration.Value;
|
||||
isRoundActive.Value = true;
|
||||
|
||||
Debug.Log($"[ROUND] START round={currentRound.Value} players={alivePlayers.Count}");
|
||||
RoundStartedClientRPC(currentRound.Value);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user