네트워크 멀티플레이 환경 문제 수정
관련 문제가 다시 발생하면 이 커밋으로 돌아올 것
This commit is contained in:
@@ -1,29 +1,34 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using Unity.Netcode;
|
||||
|
||||
namespace Northbound
|
||||
{
|
||||
/// <summary>
|
||||
/// 플레이어의 장비 소켓 관리 (손, 등, 허리 등)
|
||||
/// </summary>
|
||||
public class EquipmentSocket : MonoBehaviour
|
||||
public class EquipmentSocket : NetworkBehaviour
|
||||
{
|
||||
[System.Serializable]
|
||||
public class Socket
|
||||
{
|
||||
public string socketName; // "RightHand", "LeftHand", "Back" 등
|
||||
public Transform socketTransform; // 실제 본 Transform
|
||||
[HideInInspector] public GameObject currentEquipment; // 현재 장착된 장비
|
||||
public string socketName;
|
||||
public Transform socketTransform;
|
||||
[HideInInspector] public GameObject currentEquipment;
|
||||
}
|
||||
|
||||
[Header("Available Sockets")]
|
||||
public List<Socket> sockets = new List<Socket>();
|
||||
|
||||
[Header("Equipment Prefabs")]
|
||||
public GameObject[] equipmentPrefabs;
|
||||
|
||||
private Dictionary<string, Socket> _socketDict = new Dictionary<string, Socket>();
|
||||
private Dictionary<string, GameObject> _prefabDict = new Dictionary<string, GameObject>();
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 빠른 검색을 위한 딕셔너리 생성
|
||||
_socketDict.Clear();
|
||||
foreach (var socket in sockets)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(socket.socketName))
|
||||
@@ -31,82 +36,124 @@ namespace Northbound
|
||||
_socketDict[socket.socketName] = socket;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 소켓에 장비 부착
|
||||
/// </summary>
|
||||
public GameObject AttachToSocket(string socketName, GameObject equipmentPrefab)
|
||||
{
|
||||
if (!_socketDict.TryGetValue(socketName, out Socket socket))
|
||||
_prefabDict.Clear();
|
||||
if (equipmentPrefabs != null)
|
||||
{
|
||||
Debug.LogWarning($"소켓을 찾을 수 없습니다: {socketName}");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (socket.socketTransform == null)
|
||||
{
|
||||
Debug.LogWarning($"소켓 Transform이 없습니다: {socketName}");
|
||||
return null;
|
||||
}
|
||||
|
||||
// 기존 장비 제거
|
||||
DetachFromSocket(socketName);
|
||||
|
||||
// 새 장비 생성
|
||||
if (equipmentPrefab != null)
|
||||
{
|
||||
GameObject equipment = Instantiate(equipmentPrefab, socket.socketTransform);
|
||||
equipment.transform.localPosition = Vector3.zero;
|
||||
equipment.transform.localRotation = Quaternion.identity;
|
||||
socket.currentEquipment = equipment;
|
||||
|
||||
return equipment;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 소켓에서 장비 제거
|
||||
/// </summary>
|
||||
public void DetachFromSocket(string socketName)
|
||||
{
|
||||
if (!_socketDict.TryGetValue(socketName, out Socket socket))
|
||||
return;
|
||||
|
||||
if (socket.currentEquipment != null)
|
||||
{
|
||||
Destroy(socket.currentEquipment);
|
||||
socket.currentEquipment = null;
|
||||
foreach (var prefab in equipmentPrefabs)
|
||||
{
|
||||
if (prefab != null)
|
||||
{
|
||||
_prefabDict[prefab.name] = prefab;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모든 소켓에서 장비 제거
|
||||
/// </summary>
|
||||
public void DetachAll()
|
||||
public override void OnNetworkDespawn()
|
||||
{
|
||||
foreach (var socket in sockets)
|
||||
{
|
||||
if (socket.currentEquipment != null)
|
||||
{
|
||||
Destroy(socket.currentEquipment);
|
||||
Object.Destroy(socket.currentEquipment);
|
||||
socket.currentEquipment = null;
|
||||
}
|
||||
}
|
||||
base.OnNetworkDespawn();
|
||||
}
|
||||
|
||||
public GameObject AttachToSocket(string socketName, GameObject equipmentPrefab)
|
||||
{
|
||||
if (equipmentPrefab != null)
|
||||
{
|
||||
AttachToSocketServerRpc(socketName, equipmentPrefab.name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server)]
|
||||
private void AttachToSocketServerRpc(string socketName, string prefabName)
|
||||
{
|
||||
AttachToSocketClientRpc(socketName, prefabName);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.ClientsAndHost)]
|
||||
private void AttachToSocketClientRpc(string socketName, string prefabName)
|
||||
{
|
||||
if (!_socketDict.ContainsKey(socketName))
|
||||
return;
|
||||
|
||||
var socket = sockets.Find(s => s.socketName == socketName);
|
||||
if (socket == null || socket.socketTransform == null)
|
||||
return;
|
||||
|
||||
DetachFromSocketInternal(socketName);
|
||||
|
||||
GameObject prefab = FindPrefab(prefabName);
|
||||
if (prefab != null)
|
||||
{
|
||||
GameObject equipment = Object.Instantiate(prefab, socket.socketTransform);
|
||||
equipment.transform.localPosition = Vector3.zero;
|
||||
equipment.transform.localRotation = Quaternion.identity;
|
||||
socket.currentEquipment = equipment;
|
||||
}
|
||||
}
|
||||
|
||||
public void DetachFromSocket(string socketName)
|
||||
{
|
||||
DetachFromSocketServerRpc(socketName);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server)]
|
||||
private void DetachFromSocketServerRpc(string socketName)
|
||||
{
|
||||
DetachFromSocketClientRpc(socketName);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.ClientsAndHost)]
|
||||
private void DetachFromSocketClientRpc(string socketName)
|
||||
{
|
||||
DetachFromSocketInternal(socketName);
|
||||
}
|
||||
|
||||
private void DetachFromSocketInternal(string socketName)
|
||||
{
|
||||
var socket = sockets.Find(s => s.socketName == socketName);
|
||||
if (socket == null) return;
|
||||
|
||||
if (socket.currentEquipment != null)
|
||||
{
|
||||
Object.Destroy(socket.currentEquipment);
|
||||
socket.currentEquipment = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 특정 소켓에 장비가 있는지 확인
|
||||
/// </summary>
|
||||
public bool HasEquipment(string socketName)
|
||||
{
|
||||
if (_socketDict.TryGetValue(socketName, out Socket socket))
|
||||
var socket = sockets.Find(s => s.socketName == socketName);
|
||||
return socket != null && socket.currentEquipment != null;
|
||||
}
|
||||
|
||||
public GameObject GetEquipment(string socketName)
|
||||
{
|
||||
var socket = sockets.Find(s => s.socketName == socketName);
|
||||
return socket != null ? socket.currentEquipment : null;
|
||||
}
|
||||
|
||||
private GameObject FindPrefab(string name)
|
||||
{
|
||||
if (_prefabDict.TryGetValue(name, out var prefab))
|
||||
{
|
||||
return socket.currentEquipment != null;
|
||||
return prefab;
|
||||
}
|
||||
return false;
|
||||
|
||||
prefab = Resources.Load<GameObject>($"Prefabs/{name}");
|
||||
if (prefab != null)
|
||||
{
|
||||
return prefab;
|
||||
}
|
||||
return Resources.Load<GameObject>(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user