using UnityEngine; using System.Collections.Generic; using Unity.Netcode; namespace Northbound { public class EquipmentSocket : NetworkBehaviour { [System.Serializable] public class Socket { public string socketName; public Transform socketTransform; [HideInInspector] public GameObject currentEquipment; } [Header("Available Sockets")] public List sockets = new List(); [Header("Equipment Prefabs")] public GameObject[] equipmentPrefabs; private Dictionary _socketDict = new Dictionary(); private Dictionary _prefabDict = new Dictionary(); private void Awake() { _socketDict.Clear(); foreach (var socket in sockets) { if (!string.IsNullOrEmpty(socket.socketName)) { _socketDict[socket.socketName] = socket; } } _prefabDict.Clear(); if (equipmentPrefabs != null) { foreach (var prefab in equipmentPrefabs) { if (prefab != null) { _prefabDict[prefab.name] = prefab; } } } } public override void OnNetworkDespawn() { foreach (var socket in sockets) { if (socket.currentEquipment != null) { 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; } } public bool HasEquipment(string socketName) { 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 prefab; } prefab = Resources.Load($"Prefabs/{name}"); if (prefab != null) { return prefab; } return Resources.Load(name); } } }