using System.Collections.Generic; using System.Linq; using Unity.Netcode; using UnityEngine; namespace Northbound { /// /// 네트워크 플레이어의 스폰 위치를 관리 /// public class NetworkSpawnManager : NetworkBehaviour { public static NetworkSpawnManager Instance { get; private set; } [Header("Spawn Settings")] public List spawnPoints = new List(); public bool useRandomSpawn = false; public bool findSpawnPointsAutomatically = true; private Dictionary _clientSpawnIndices = new Dictionary(); private int _nextSpawnIndex = 0; private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; } private void Start() { if (findSpawnPointsAutomatically) { FindSpawnPoints(); } if (NetworkManager.Singleton != null) { NetworkManager.Singleton.OnClientConnectedCallback += OnClientConnected; } } private void FindSpawnPoints() { PlayerSpawnPoint[] points = FindObjectsByType(FindObjectsSortMode.None); // spawnIndex로 정렬 var sortedPoints = points.OrderBy(p => p.spawnIndex == -1 ? int.MaxValue : p.spawnIndex); spawnPoints.Clear(); foreach (var point in sortedPoints) { if (point.isAvailable) { spawnPoints.Add(point.transform); } } Debug.Log($"[SpawnManager] {spawnPoints.Count}개의 스폰 포인트를 찾았습니다."); } private void OnClientConnected(ulong clientId) { if (!IsServer) return; // 플레이어가 스폰되었을 때 위치 설정 if (NetworkManager.Singleton.ConnectedClients.TryGetValue(clientId, out var client)) { if (client.PlayerObject != null) { Vector3 spawnPosition = GetSpawnPosition(clientId); Quaternion spawnRotation = GetSpawnRotation(clientId); client.PlayerObject.transform.position = spawnPosition; client.PlayerObject.transform.rotation = spawnRotation; Debug.Log($"[SpawnManager] 클라이언트 {clientId} 스폰 위치 설정: {spawnPosition}"); } } } public Vector3 GetSpawnPosition(ulong clientId) { if (spawnPoints.Count == 0) { Debug.LogWarning("[SpawnManager] 스폰 포인트가 없습니다. 기본 위치 반환."); return Vector3.zero; } int spawnIndex; if (useRandomSpawn) { spawnIndex = Random.Range(0, spawnPoints.Count); } else { if (!_clientSpawnIndices.ContainsKey(clientId)) { _clientSpawnIndices[clientId] = _nextSpawnIndex; _nextSpawnIndex = (_nextSpawnIndex + 1) % spawnPoints.Count; } spawnIndex = _clientSpawnIndices[clientId]; } return spawnPoints[spawnIndex].position; } public Quaternion GetSpawnRotation(ulong clientId) { if (spawnPoints.Count == 0) return Quaternion.identity; int spawnIndex = _clientSpawnIndices.ContainsKey(clientId) ? _clientSpawnIndices[clientId] : 0; return spawnPoints[spawnIndex].rotation; } override public void OnDestroy() { if (NetworkManager.Singleton != null) { NetworkManager.Singleton.OnClientConnectedCallback -= OnClientConnected; } base.OnDestroy(); } } }