using System.Collections.Generic; using System.Linq; using Unity.Netcode; using UnityEngine; namespace Northbound { /// /// 네트워크 연결 및 스폰 관리 /// public class NetworkConnectionHandler : MonoBehaviour { [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; // ⭐ Awake에서 스폰 포인트 먼저 찾고, 콜백 등록 private void Awake() { // 1️⃣ 먼저 스폰 포인트 찾기 if (findSpawnPointsAutomatically) { FindSpawnPoints(); } // 2️⃣ 그 다음 콜백 등록 if (NetworkManager.Singleton != null) { NetworkManager.Singleton.ConnectionApprovalCallback = ApprovalCheck; NetworkManager.Singleton.OnServerStarted += OnServerStarted; Debug.Log("[Connection] ConnectionApprovalCallback 등록됨"); } else { Debug.LogError("[Connection] NetworkManager.Singleton이 null입니다!"); } } 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($"[Connection] {spawnPoints.Count}개의 스폰 포인트를 찾았습니다."); } private void OnServerStarted() { Debug.Log("[Connection] 서버 시작됨"); } private void ApprovalCheck( NetworkManager.ConnectionApprovalRequest request, NetworkManager.ConnectionApprovalResponse response) { // 🔍 디버깅: 스폰 포인트 상태 확인 if (spawnPoints.Count == 0) { Debug.LogError($"[Connection] 스폰 포인트가 없습니다! 씬에 PlayerSpawnPoint가 있는지 확인하세요."); } response.Approved = true; response.CreatePlayerObject = true; // 스폰 위치 설정 response.Position = GetSpawnPosition(request.ClientNetworkId); response.Rotation = GetSpawnRotation(request.ClientNetworkId); Debug.Log($"[Connection] 클라이언트 {request.ClientNetworkId} 승인됨. 스폰 위치: {response.Position}"); } private Vector3 GetSpawnPosition(ulong clientId) { if (spawnPoints.Count == 0) { Debug.LogWarning("[Connection] 스폰 포인트가 없습니다. 기본 위치 반환."); 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]; } Debug.Log($"[Connection] 클라이언트 {clientId}에게 스폰 인덱스 {spawnIndex} 할당"); return spawnPoints[spawnIndex].position; } private Quaternion GetSpawnRotation(ulong clientId) { if (spawnPoints.Count == 0) return Quaternion.identity; int spawnIndex = _clientSpawnIndices.ContainsKey(clientId) ? _clientSpawnIndices[clientId] : 0; return spawnPoints[spawnIndex].rotation; } private void OnDestroy() { if (NetworkManager.Singleton != null) { NetworkManager.Singleton.ConnectionApprovalCallback = null; NetworkManager.Singleton.OnServerStarted -= OnServerStarted; } } } }