using System;
using UnityEngine;
///
/// Types of equipment slots available.
///
public enum EquipmentSlotType
{
MainHand,
OffHand,
Head,
Body,
Back,
Accessory
}
///
/// Represents a single equipment slot that can hold an equipped item.
///
[Serializable]
public class EquipmentSlot
{
///
/// Type of this equipment slot.
///
public EquipmentSlotType SlotType;
///
/// Transform where equipment is attached.
///
public Transform AttachPoint;
///
/// Currently spawned equipment instance.
///
[NonSerialized]
public GameObject CurrentEquipment;
///
/// Currently equipped item data.
///
[NonSerialized]
public ItemData EquippedItem;
///
/// Event fired when equipment changes.
///
public event Action OnEquipmentChanged;
///
/// Equip an item to this slot.
///
/// Item to equip (or null to unequip)
public void Equip(ItemData item)
{
// Remove current equipment
Unequip();
if (item == null) return;
// Check if item can be equipped
if (!item.CanBeEquipped) return;
EquippedItem = item;
// Spawn equipment visual
var prefab = item.GetEquipmentPrefab();
if (prefab != null && AttachPoint != null)
{
CurrentEquipment = UnityEngine.Object.Instantiate(prefab, AttachPoint);
CurrentEquipment.transform.localPosition = item.GetPositionOffset();
CurrentEquipment.transform.localRotation = Quaternion.Euler(item.GetRotationOffset());
}
OnEquipmentChanged?.Invoke(this, item);
}
///
/// Equip using IEquippableItem interface (more generic).
///
/// Equippable item
/// The user equipping the item
public void Equip(IEquippableItem equippable, GameObject user)
{
Unequip();
if (equippable == null) return;
var prefab = equippable.GetEquipmentPrefab();
if (prefab == null) return;
// Find or use the configured attach point
Transform attachTo = AttachPoint;
if (attachTo == null && user != null)
{
attachTo = equippable.FindAttachmentPoint(user);
}
if (attachTo != null)
{
CurrentEquipment = UnityEngine.Object.Instantiate(prefab, attachTo);
CurrentEquipment.transform.localPosition = equippable.GetPositionOffset();
CurrentEquipment.transform.localRotation = Quaternion.Euler(equippable.GetRotationOffset());
}
OnEquipmentChanged?.Invoke(this, EquippedItem);
}
///
/// Unequip the current item.
///
public void Unequip()
{
if (CurrentEquipment != null)
{
UnityEngine.Object.Destroy(CurrentEquipment);
CurrentEquipment = null;
}
var previousItem = EquippedItem;
EquippedItem = null;
if (previousItem != null)
{
OnEquipmentChanged?.Invoke(this, null);
}
}
///
/// Check if this slot has equipment.
///
public bool HasEquipment => CurrentEquipment != null || EquippedItem != null;
///
/// Check if a specific item can be equipped in this slot.
///
public bool CanEquip(ItemData item)
{
if (item == null) return true; // Can always "unequip"
return item.CanBeEquipped;
}
}
///
/// Manages multiple equipment slots for a character.
///
[Serializable]
public class EquipmentManager
{
[SerializeField]
private EquipmentSlot[] _slots;
///
/// All equipment slots.
///
public EquipmentSlot[] Slots => _slots;
///
/// Get a slot by type.
///
public EquipmentSlot GetSlot(EquipmentSlotType type)
{
if (_slots == null) return null;
foreach (var slot in _slots)
{
if (slot.SlotType == type)
return slot;
}
return null;
}
///
/// Equip an item to the appropriate slot.
///
public bool TryEquip(ItemData item, EquipmentSlotType preferredSlot = EquipmentSlotType.MainHand)
{
var slot = GetSlot(preferredSlot);
if (slot != null && slot.CanEquip(item))
{
slot.Equip(item);
return true;
}
return false;
}
///
/// Unequip all slots.
///
public void UnequipAll()
{
if (_slots == null) return;
foreach (var slot in _slots)
{
slot.Unequip();
}
}
///
/// Initialize slots with attach points found on the character.
///
public void Initialize(GameObject character, params (EquipmentSlotType type, string attachPointName)[] slotConfigs)
{
_slots = new EquipmentSlot[slotConfigs.Length];
for (int i = 0; i < slotConfigs.Length; i++)
{
var config = slotConfigs[i];
Transform attachPoint = null;
// Find attach point
var transforms = character.GetComponentsInChildren();
foreach (var t in transforms)
{
if (t.name == config.attachPointName)
{
attachPoint = t;
break;
}
}
_slots[i] = new EquipmentSlot
{
SlotType = config.type,
AttachPoint = attachPoint
};
}
}
}