134 lines
4.3 KiB
C#
134 lines
4.3 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Unity.Netcode;
|
|
using UnityEngine;
|
|
|
|
namespace Northbound
|
|
{
|
|
/// <summary>
|
|
/// 네트워크 플레이어의 스폰 위치를 관리
|
|
/// </summary>
|
|
public class NetworkSpawnManager : NetworkBehaviour
|
|
{
|
|
public static NetworkSpawnManager Instance { get; private set; }
|
|
|
|
[Header("Spawn Settings")]
|
|
public List<Transform> spawnPoints = new List<Transform>();
|
|
public bool useRandomSpawn = false;
|
|
public bool findSpawnPointsAutomatically = true;
|
|
|
|
private Dictionary<ulong, int> _clientSpawnIndices = new Dictionary<ulong, int>();
|
|
private NetworkVariable<int> networkNextSpawnIndex = new NetworkVariable<int>(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<PlayerSpawnPoint>(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($"<color=cyan>[SpawnManager] {spawnPoints.Count}개의 스폰 포인트를 찾았습니다.</color>");
|
|
}
|
|
|
|
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($"<color=green>[SpawnManager] 클라이언트 {clientId} 스폰 위치 설정: {spawnPosition}</color>");
|
|
}
|
|
}
|
|
}
|
|
|
|
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] = networkNextSpawnIndex.Value;
|
|
networkNextSpawnIndex.Value = (networkNextSpawnIndex.Value + 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();
|
|
}
|
|
}
|
|
} |