6일차 - 장비 시스템 구현

네,가능합니다 ㅣ 2025. 1. 27. 14:57

1. 장비 기본 구조 설계

 

장비는 ScriptableObject를 활용하여 데이터를 관리하도록 구현

[CreateAssetMenu(fileName = "New Equipment", menuName = "Game/Equipment")]
public class Equipment : ScriptableObject
{
    public EnumTypes.EquipmentType equipmentType { get; set; }
    public string Id;
    public string Name;
    public EquipmentGrade Grade;
    public EquipmentSlot Slot;
    public Sprite icon;
    public GameObject prefab;
    public List<EquipmentStat> Stats = new();
}

 

2. 장비 스탯 시스템

 

장비에 적용되는 스탯은 퍼센트와 고정값을 모두 지원하도록 구현

[System.Serializable]
public class EquipmentStat
{
    public StatType Type;
    public float Value;
    public bool IsPercentage; // true면 퍼센트 값으로 적용
}

 

3. 장비 시스템 구현

 

장비 장착/해제 및 모델 관리를 담당하는 시스템 구현

public class EquipmentSystem : MonoBehaviour
{
    private Dictionary<EquipmentSlot, Equipment> equippedItems = new();
    private Dictionary<EquipmentSlot, GameObject> equippedObjects = new();

    public bool EquipItem(Equipment item)
    {
        if (equippedItems.ContainsKey(item.Slot))
        {
            UnequipItem(item.Slot);
        }

        equippedItems[item.Slot] = item;
        ApplyEquipmentStats(item);
        SpawnEquipmentModel(item);
        
        EventManager.Dispatch(EnumTypes.GameEventType.EquipmentChanged, item.Slot);
        return true;
    }

    private void SpawnEquipmentModel(Equipment item)
    {
        if (item.prefab == null) return;

        Transform mountPoint = GetMountPoint(item.Slot);
        if (mountPoint == null) return;

        // 새 장비 모델 생성 및 장착
        GameObject equipmentObj = Instantiate(item.prefab, mountPoint);
        equipmentObj.transform.localPosition = Vector3.zero;
        equipmentObj.transform.localRotation = Quaternion.identity;
        equippedObjects[item.Slot] = equipmentObj;
    }
}

 

4. UI 시스템 구현

 

장비 UI와 인벤토리 UI를 연동하여 작동하도록 구현

public class UIEquipment : UIBase
{
    private Dictionary<EquipmentSlot, Image> slotIcons;
    private Dictionary<EquipmentSlot, TMP_Text> slotNames;

    public override void Opened(object[] param)
    {
        base.Opened(param);
        
        equipmentSystem = Managers.Character.Player.Equipment;
        InitializeSlotDictionaries();
        InitializeButtons();
        
        // 이벤트 구독으로 인벤토리와 연동
        EventManager.Subscribe(EnumTypes.GameEventType.EquipmentChanged, OnEquipmentChanged);
        
        RefreshAllSlots();
    }

    private void OnEquipmentChanged(object param)
    {
        if (param is EquipmentSlot slot)
        {
            RefreshSlot(slot);
        }
    }
}

 

주요 특징

 

1. 이벤트 기반 시스템

 

  • 장비 변경 시 이벤트를 발생시켜 UI 갱신
  • 느슨한 결합을 통한 확장성 확보
  • EventManager를 통한 중앙 집중식 이벤트 관리

 

2. 모듈화된 구조

 

  • 각 시스템이 독립적으로 동작하도록 설계
  • 인터페이스를 통한 명확한 책임 분리
  • 재사용 가능한 컴포넌트 구조