코드 리팩토링
재사용성 및 확장성을 고려하여 코드 전반을 리팩토링함
This commit is contained in:
230
Assets/Scripts/Player/EquipmentSlot.cs
Normal file
230
Assets/Scripts/Player/EquipmentSlot.cs
Normal file
@@ -0,0 +1,230 @@
|
||||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
/// <summary>
|
||||
/// Types of equipment slots available.
|
||||
/// </summary>
|
||||
public enum EquipmentSlotType
|
||||
{
|
||||
MainHand,
|
||||
OffHand,
|
||||
Head,
|
||||
Body,
|
||||
Back,
|
||||
Accessory
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a single equipment slot that can hold an equipped item.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class EquipmentSlot
|
||||
{
|
||||
/// <summary>
|
||||
/// Type of this equipment slot.
|
||||
/// </summary>
|
||||
public EquipmentSlotType SlotType;
|
||||
|
||||
/// <summary>
|
||||
/// Transform where equipment is attached.
|
||||
/// </summary>
|
||||
public Transform AttachPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Currently spawned equipment instance.
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public GameObject CurrentEquipment;
|
||||
|
||||
/// <summary>
|
||||
/// Currently equipped item data.
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
public ItemData EquippedItem;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when equipment changes.
|
||||
/// </summary>
|
||||
public event Action<EquipmentSlot, ItemData> OnEquipmentChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Equip an item to this slot.
|
||||
/// </summary>
|
||||
/// <param name="item">Item to equip (or null to unequip)</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equip using IEquippableItem interface (more generic).
|
||||
/// </summary>
|
||||
/// <param name="equippable">Equippable item</param>
|
||||
/// <param name="user">The user equipping the item</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unequip the current item.
|
||||
/// </summary>
|
||||
public void Unequip()
|
||||
{
|
||||
if (CurrentEquipment != null)
|
||||
{
|
||||
UnityEngine.Object.Destroy(CurrentEquipment);
|
||||
CurrentEquipment = null;
|
||||
}
|
||||
|
||||
var previousItem = EquippedItem;
|
||||
EquippedItem = null;
|
||||
|
||||
if (previousItem != null)
|
||||
{
|
||||
OnEquipmentChanged?.Invoke(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Check if this slot has equipment.
|
||||
/// </summary>
|
||||
public bool HasEquipment => CurrentEquipment != null || EquippedItem != null;
|
||||
|
||||
/// <summary>
|
||||
/// Check if a specific item can be equipped in this slot.
|
||||
/// </summary>
|
||||
public bool CanEquip(ItemData item)
|
||||
{
|
||||
if (item == null) return true; // Can always "unequip"
|
||||
return item.CanBeEquipped;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Manages multiple equipment slots for a character.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class EquipmentManager
|
||||
{
|
||||
[SerializeField]
|
||||
private EquipmentSlot[] _slots;
|
||||
|
||||
/// <summary>
|
||||
/// All equipment slots.
|
||||
/// </summary>
|
||||
public EquipmentSlot[] Slots => _slots;
|
||||
|
||||
/// <summary>
|
||||
/// Get a slot by type.
|
||||
/// </summary>
|
||||
public EquipmentSlot GetSlot(EquipmentSlotType type)
|
||||
{
|
||||
if (_slots == null) return null;
|
||||
|
||||
foreach (var slot in _slots)
|
||||
{
|
||||
if (slot.SlotType == type)
|
||||
return slot;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Equip an item to the appropriate slot.
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unequip all slots.
|
||||
/// </summary>
|
||||
public void UnequipAll()
|
||||
{
|
||||
if (_slots == null) return;
|
||||
|
||||
foreach (var slot in _slots)
|
||||
{
|
||||
slot.Unequip();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initialize slots with attach points found on the character.
|
||||
/// </summary>
|
||||
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<Transform>();
|
||||
foreach (var t in transforms)
|
||||
{
|
||||
if (t.name == config.attachPointName)
|
||||
{
|
||||
attachPoint = t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_slots[i] = new EquipmentSlot
|
||||
{
|
||||
SlotType = config.type,
|
||||
AttachPoint = attachPoint
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user