내일배움캠프 46일차 TIL <Unity 2D 클리커 게임 만들기> 06/13

정광훈(Unity_9기)·2025년 6월 13일

TIL (Today I Learned)

목록 보기
56/110
post-thumbnail

오늘 작업

<정리>

무기 가방에 처음 시작 무기로 나무검을 사용할 수 있도록 함.
무기의 이미지와 이름, 레벨, 능력치들도 UI에 표시되도록 함.
장착버튼을 누르면 장착됨.

==================

  • 이후 해야할 일
    무기 가방에 기본 무기인 나무검만 등록한 상태
    장착한 무기가 메인 화면UI에 출력되도록 해야 함.
    플레이어 능력치와 합산되도록 해야 함.
    강화 기능도 구현 해야 함.

여기까지 했으면 무기만 더 추가해서 반복하면 됨.


<스크립트>

<WeaponData.cs>

using System.Collections.Generic;
using UnityEngine;

public enum WeaponStatType
{
    Damage, // 대미지
    CriticalChance // 크리티컬 확률
}

[CreateAssetMenu(fileName = "New WeaponData", menuName = "WeaponStat")]
public class WeaponData : ScriptableObject // 아이템의 스탯 데이터를 저장
{
    [Header("기본 정보")]
    public string weaponName; // 무기 이름
    public int weaponLevel; // 무기 레벨
    public List<WeaponStatEntry> weaponStats; // 무기 스텟 리스트
    public Sprite weaponSprite; // 무기 스프라이트 

    [Header("강화 정보")] public int maxLevel; // 무기 최대 레벨
    public int damageIncreasePerLevel; // 레벨당 대미지 증가량
    public int critChanceIncreasePerLevel; // 레벨당 크리티컬 확률 증가량
    
    [Header("구매 비용")]
    public int purchaseCost;
    
    public int GetDamage(int level) // 무기 SO에서 현재 대미지 값 가져오기
    {
        int baseWeaponDamage = 0; // 무기 기본 대미지

        foreach (WeaponStatEntry weaponStat in weaponStats)
        {
            if (weaponStat.weaponStatType == WeaponStatType.Damage)
            {
                // 무기 SO에 저장된 대미지 기본값을 저장
                baseWeaponDamage = weaponStat.baseValue;
                break;
            }
        }

        // 무기 레벨업 시 증가하는 대미지 량
        // 무기 기본 대미지 + (레벨당 증가하는 대미지 * 무기 레벨)
        return baseWeaponDamage + damageIncreasePerLevel * level;
    }

    public int GetCritChance(int level) // 무기 SO에서 현재 크리티컬 확률 값 가져오기
    { 
        int baseWeaponCritChance = 0; // 무기 기본 크리티컬 확률

        foreach (WeaponStatEntry weaponStat in weaponStats)
        {
            if (weaponStat.weaponStatType == WeaponStatType.CriticalChance)
            {
                // 무기 SO에 저장된 크리티컬 확률 기본값을 저장
                baseWeaponCritChance = weaponStat.baseValue;
                break;
            }
        }

        // 무기 레벨업 시 증가하는 크리티컬 확률 량
        // 무기 기본 크리티컬 확률 + (레벨당 증가하는 크리티컬 확률 * 무기 레벨)
        return baseWeaponCritChance + critChanceIncreasePerLevel * level;
    }
}

[System.Serializable]
public class WeaponStatEntry // 아이템 스탯 정보 정의
{
    public WeaponStatType weaponStatType; // 어떤 종류의 능력치인지
    public int baseValue; // 해당 능력치의 기본 값
}

=============
<PlayerWeapon.cs>

using UnityEngine;

[System.Serializable]
public class PlayerWeapon // 플레이어가 소유한 특정 무기 데이터와 상태를 관리
{
    public WeaponData weaponData; // 이 무기의 기본 정보 
    public int currentLevel; // 플레이어가 소유한 이 무기 인스턴스의 현재 레벨
    
    // WeaponData와 함께 이 무기 인스턴스의 초기 레벨을 받음
    public PlayerWeapon(WeaponData data, int initialLevel)
    {
        weaponData = data;
        currentLevel = initialLevel;
    }
    
    public int GetCurrentDamage() // 이 PlayerWeapon 인스턴스의 'currentLevel'을 사용
    {
        // WeaponData의 GetDamage 메서드를 활용하여 현재 레벨의 데미지를 계산
        return weaponData.GetDamage(currentLevel);
    }
    
    public int GetCurrentCritChance() // 이 PlayerWeapon 인스턴스의 'currentLevel'을 사용
    { 
        // WeaponData의 GetCritChance 메서드를 활용하여 현재 레벨의 치명타 확률을 계산
        return weaponData.GetCritChance(currentLevel);
    }
    
    public void WeaponLevelUp() // 무기 업그레이드시 레벨업
    {
        // 현재 무기 레벨 = 무기 최대 레벨이면 false반환
        if (currentLevel  == weaponData.maxLevel)
        {
            Debug.Log("만렙이라 불가");
            return;
        }

        currentLevel++; // 현재 무기 레벨 증가
        Debug.Log($"WeaponLevelUp: '{weaponData.weaponName}' 레벨 업! 현재 레벨: {currentLevel}");
    }
}

========
<EquipmentManager.cs>

using System;
using UnityEngine;

public class EquipmentManager : MonoBehaviour // 무기 장착 관리
{ 
    public static EquipmentManager Instance {get; private set;}
    
    public PlayerWeapon equippedWeapon{ get; private set; } // 현재 장착된 무기 인스턴스

    // 장비 변경 시 다른 스크립트에 알리는 이벤트
    public static event Action OnEquipmentChanged;
    
    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    public void EquipWeapon(PlayerWeapon newWeaponToEquip) // 장착할 무기
    {
        if (equippedWeapon != newWeaponToEquip) // 이미 장착된 무기가 아니면
        {
            equippedWeapon = newWeaponToEquip;
            Debug.Log(equippedWeapon.weaponData.weaponName + " 장착");
            
            // 장착이 완료된 후 OnEquipmentChanged 이벤트를 발생
            OnEquipmentChanged?.Invoke();
        }
    }

    public void UnEquipWeapon() // 해제할 무기
    {
        if (equippedWeapon != null)
        {
            string weaponName = equippedWeapon.weaponData.weaponName;
            equippedWeapon = null; // 무기 해제
            Debug.Log(weaponName + " 해제");
        }
        
        //장비 해제 후에도 OnEquipmentChanged 이벤트를 발생
        // OnEquipmentChanged?.Invoke();
    }
}

=========
<InventoryManager.cs>

using System.Collections.Generic;
using UnityEngine;

public class InventoryManager : MonoBehaviour // 플레이어가 소유한 무기를 관리하는 매니저
{
    public static InventoryManager Instance { get; private set; }

    // 플레이어가 소유한 무기 리스트
    public List<PlayerWeapon> playerWeapons = new List<PlayerWeapon>();
    // 게임 시작 시 플레이어 인벤토리에 추가될 초기 무기 데이터 목록
    public List<WeaponData> initialWeaponDataList;

    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }

    void Start()
    {
        // 게임 시작 시, 인스펙터에 설정된 초기 무기들을 인벤토리에 추가
        foreach (WeaponData data in initialWeaponDataList)
        {
            // 게임 시작 시 초기 무기를 인벤토리에 추가
            if (!playerWeapons.Exists(w => w.weaponData == data))
            {
                AddNewWeapon(data);
            }
        }
    }

    public void AddNewWeapon(WeaponData weaponData) // 인벤토리에 새로운 무기를 추가
    {
        // 새로운 무기를 소유한 무기 리스트에 추가
        PlayerWeapon newWeapon = new PlayerWeapon(weaponData, weaponData.weaponLevel);
        playerWeapons.Add(newWeapon);
        Debug.Log($"InventoryManager: '{weaponData.weaponName}' (Lv.{newWeapon.currentLevel})이 인벤토리에 추가");
    }

    // 인벤토리에서 특정 WeaponData를 가진 PlayerWeapon을 찾는 메서드
    public PlayerWeapon GetPlayerWeapon(WeaponData data)
    {
        return playerWeapons.Find(w => w.weaponData == data);
    }
}

=======
<WeaponSlotUI.cs>

using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class WeaponSlotUI : MonoBehaviour
{
    [Header("UI참조")] public Image weaponImage; // 무기 스프라이트 Image 컴포넌트

    public TextMeshProUGUI weaponNameText; // 무기 이름 텍스트
    [SerializeField] private TextMeshProUGUI weaponDamageText; // 무기 공격력 텍스트
    [SerializeField] private TextMeshProUGUI weaponCritChanceText; // 무기 치명타 확률 텍스트
    [SerializeField] private TextMeshProUGUI weaponCostText; // 무기 가격

    [Header("버튼 GameObject 참조")] public GameObject purchaseButtonGO;
    public GameObject changeButtonGO;
    public GameObject upgradeButtonGO;

    [Header("무기 SO 에셋")] public WeaponData weaponDataAsset;

    // 현재 이 UI 슬롯이 나타내는 무기 데이터
    private WeaponData _currentWeaponData;

    // 이 슬롯에 해당하는 무기의 소유 여부와 현재 레벨 (게임 시작 시 초기화)
    private bool hasWeapon = false; // 무기를 소유하고 있는지
    private int currentWeaponLevel = 0;

    void Awake()
    {
        // 필수 인스턴스 존재 여부 확인
        if (BtnClick.Instance == null)
        {
            Debug.Log("WeaponSlotUI: BtnClick.Instance를 찾을 수 없음", this);
            enabled = false;
            return;
        }

        if (EquipmentManager.Instance == null)
        {
            Debug.Log("WeaponSlotUI: EquipmentManager.Instance를 찾을 수 없음", this);
            enabled = false;
            return;
        }

        if (InventoryManager.Instance == null)
        {
            Debug.Log("WeaponSlotUI: InventoryManager.Instance를 찾을 수 없음", this);
            enabled = false;
            return;
        }

        // weaponDataAsset이 할당되었는지 확인하고 사용
        if (weaponDataAsset != null)
        {
            _currentWeaponData = weaponDataAsset; // 직접 할당된 WeaponData를 사용합니다.
        }
        else
        {
            Debug.Log("WeaponSlotUI: 'Weapon Data Asset'이 인스펙터에 할당되지 않음. 스크립트 비활성화.", this);
            enabled = false;
            return;
        }

        // 초기 상태 설정: InventoryManager에서 해당 무기를 가지고 있는지 확인
        PlayerWeapon existingWeapon = InventoryManager.Instance.GetPlayerWeapon(_currentWeaponData);
        if (existingWeapon != null)
        {
            hasWeapon = true;
            currentWeaponLevel = existingWeapon.currentLevel;
        }
        else
        {
            hasWeapon = false;
            currentWeaponLevel = _currentWeaponData.weaponLevel; // 구매 전에는 WeaponData의 기본 레벨 표시
        }

        BtnClick.Instance.onWeaponPanelClicked.AddListener(OnWeaponPanelOpened);
        BtnClick.Instance.onWeaponBuyClicked.AddListener(OnWeaponBuy);
        BtnClick.Instance.onWeaponChangeClicked.AddListener(OnWeaponChange);

        // EquipmentManager의 장비 변경 이벤트 구독 (장착 상태 변화 감지)
        EquipmentManager.OnEquipmentChanged += OnEquipmentChanged;
    }

    void Start()
    {
        UpdateWeaponSlotUI();
    }

    void OnDestroy()
    {
        // 구독 해지 (오브젝트 수명 관리를 위해 권장)
        if (BtnClick.Instance != null)
        {
            BtnClick.Instance.onWeaponPanelClicked.RemoveListener(OnWeaponPanelOpened);
            BtnClick.Instance.onWeaponBuyClicked.RemoveListener(OnWeaponBuy);
            BtnClick.Instance.onWeaponChangeClicked.RemoveListener(OnWeaponChange);
        }

        if (EquipmentManager.Instance != null)
        {
            EquipmentManager.OnEquipmentChanged -= OnEquipmentChanged;
        }
    }

    public void OnEquipmentChanged()
    {
        Debug.Log("WeaponSlotUI: 장착된 무기가 변경되었습니다. UI를 갱신합니다.");
        UpdateWeaponSlotUI();
    }

    // 무기 패널이 열렸을 때 UI 갱신
    public void OnWeaponPanelOpened()
    {
        Debug.Log("WeaponSlotUI: 무기 패널이 열림. UI를 갱신");

        if (InventoryManager.Instance == null)
        {
            Debug.LogError("WeaponSlotUI: InventoryManager.Instance가 null", this);
            return;
        }

        if (_currentWeaponData == null)
        {
            Debug.LogError("WeaponSlotUI: _currentWeaponData가 null", this);
            return;
        }

        // 인벤토리에서 최신 상태를 가져와 UI 업데이트
        PlayerWeapon existingWeapon = InventoryManager.Instance.GetPlayerWeapon(_currentWeaponData);
        if (existingWeapon != null)
        {
            hasWeapon = true;
            currentWeaponLevel = existingWeapon.currentLevel;
        }
        else
        {
            hasWeapon = false;
            currentWeaponLevel = _currentWeaponData.weaponLevel;
        }

        UpdateWeaponSlotUI();
    }

    public void OnWeaponBuy() // 무기 구매 처리
    {
        if (_currentWeaponData == null)
        {
            Debug.Log("WeaponSlotUI: _currentWeaponData가 준비되지 않음. 무기 구매를 처리할 수 없음");
            return;
        }

        int cost = _currentWeaponData.purchaseCost;

        if (BtnClick.Instance.Gold >= cost)
        {
            BtnClick.Instance.Gold -= cost;

            InventoryManager.Instance.AddNewWeapon(_currentWeaponData);

            hasWeapon = true;
            currentWeaponLevel = _currentWeaponData.weaponLevel;

            UpdateWeaponSlotUI();
            Debug.Log($"WeaponSlotUI: 무기 '{_currentWeaponData.weaponName}' 구매 성공! 잔액: {BtnClick.Instance.Gold}");
        }
    }

    public void OnWeaponChange() // 무기 장착 처리
    {
        if (_currentWeaponData == null)
        {
            Debug.Log("WeaponSlotUI: _currentWeaponData가 준비되지 않았습니다. 무기를 장착할 수 없음");
            return;
        }

        PlayerWeapon weaponToEquip = InventoryManager.Instance.GetPlayerWeapon(_currentWeaponData);
        if (weaponToEquip == null)
        {
            Debug.Log($"WeaponSlotUI: 인벤토리에서 {_currentWeaponData.weaponName}을(를) 찾을 수 없습니다. 장착할 수 없음");
            return;
        }

        // EquipmentManager의 EquipWeapon 메서드 호출
        if (EquipmentManager.Instance != null)
        {
            EquipmentManager.Instance.EquipWeapon(weaponToEquip);
        }
        else
        {
            Debug.Log("WeaponSlotUI: EquipmentManager.Instance가 null입니다. 무기를 장착할 수 없음");
        }

        Debug.Log($"WeaponSlotUI: 무기 {weaponToEquip.weaponData.weaponName} Lv.{weaponToEquip.currentLevel} 장착 완료!");
    }

    public void UpdateWeaponSlotUI()
    {
        if (_currentWeaponData == null)
        {
            Debug.Log("WeaponSlotUI: _currentWeaponData가 없어 UI 업데이트를 할 수 없음");
            return;
        }

        weaponImage.sprite = _currentWeaponData.weaponSprite;

        bool isWeaponEquipped = (EquipmentManager.Instance.equippedWeapon != null &&
                                 EquipmentManager.Instance.equippedWeapon.weaponData == _currentWeaponData);

        if (hasWeapon) // 무기를 소유하고 있는 경우
        {
            purchaseButtonGO.SetActive(false);
            changeButtonGO.SetActive(!isWeaponEquipped);
            upgradeButtonGO.SetActive(currentWeaponLevel < _currentWeaponData.maxLevel);

            // 소유한 무기는 현재 레벨 기준으로 정보 표시

            weaponNameText.text = $"{_currentWeaponData.weaponName} Lv.{currentWeaponLevel}";
            weaponDamageText.text =
                $"공격력: {_currentWeaponData.GetDamage(currentWeaponLevel)}"; // WeaponData의 GetDamage 사용
            weaponCritChanceText.text =
                $"크리티컬 확률: {_currentWeaponData.GetCritChance(currentWeaponLevel)}%"; // WeaponData의 GetCritChance 사용
        }
        else // 무기를 소유하고 있지 않은 경우 (구매 버튼 활성화, 장착/강화 버튼 비활성화)
        {
            purchaseButtonGO.SetActive(true);
            changeButtonGO.SetActive(false);
            upgradeButtonGO.SetActive(false);

            // 구매 전에는 WeaponData의 기본 레벨 (보통 1) 기준으로 정보 표시
            weaponNameText.text = _currentWeaponData.weaponName;
            weaponDamageText.text = $"공격력: {_currentWeaponData.GetDamage(_currentWeaponData.weaponLevel)}";
            weaponCritChanceText.text =
                $"치명타 확률: {_currentWeaponData.GetCritChance(_currentWeaponData.weaponLevel)}%";
            weaponCostText.text = _currentWeaponData.purchaseCost.ToString(); // 구매 가격 표시
        }
    }

    private int GetEquippedWeaponCurrentDamage()
    {
        if (EquipmentManager.Instance != null && EquipmentManager.Instance.equippedWeapon != null)
        {
            return EquipmentManager.Instance.equippedWeapon.GetCurrentDamage();
        }

        Debug.LogWarning("WeaponSlotUI: 현재 장착된 무기가 없거나 EquipmentManager가 초기화되지 않음. 기본 데미지 1을 반환");
        return 1;
    }

    private int GetEquippedWeaponCurrentCritChance()
    {
        if (EquipmentManager.Instance != null && EquipmentManager.Instance.equippedWeapon != null)
        {
            return EquipmentManager.Instance.equippedWeapon.GetCurrentCritChance();
        }

        Debug.LogWarning("WeaponSlotUI: 현재 장착된 무기가 없거나 EquipmentManager가 초기화되지 않음. 기본 치명타 확률 0을 반환");
        return 0;
    }
}

============
<BtnClick.cs>

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;

public class BtnClick : MonoBehaviour
{
    public static BtnClick Instance { get; private set; }
    
    public UnityEvent onWeaponPanelClicked;
    public UnityEvent onWeaponBuyClicked;
    public UnityEvent onWeaponChangeClicked;
    
    public static event Action OnNewGameButtonClick; 

    public GameObject CloseScene, OpenScene; //화면전환
    public GameObject StartScene, GameScene; //씬
    public GameObject WeaponChangeUpgrade; //무기 장착 밑 강화칸
    public GameObject NotEnoughGold, NotEnoughPoint; //재화 부족알림
    public GameObject Weapon1BuyBtn, Weapon1UpgradeBtn, Weapon1ChangeBtn; //무기 1구매,업그레이드,교체버튼
    public int Gold = 0;
    int Point = 0;

    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
            
            if (onWeaponPanelClicked == null) onWeaponPanelClicked = new UnityEvent();
            if (onWeaponBuyClicked == null) onWeaponBuyClicked = new UnityEvent();
            if (onWeaponChangeClicked == null) onWeaponChangeClicked = new UnityEvent();
        }
        else
        {
            Destroy(gameObject);
        }
    }
    
    public void WeaponChangeUpgradeBtnClick()//무기 변경/강화창 열기 버튼
    {
        WeaponChangeUpgrade.SetActive(true);
        onWeaponPanelClicked?.Invoke();
    }
    public void WeaponChangeUpgradeCloseBtnClick() //무기 변경/강화창 닫기 버튼
    {
        WeaponChangeUpgrade.SetActive(false);
    }
    
    public void Weapon1BuyBtnClick() //무기1 구매 버튼
    {
        onWeaponBuyClicked?.Invoke();
        
        // if (Gold >= 0)
        // {
        //     Weapon1BuyBtn.SetActive(false);
        //     Weapon1UpgradeBtn.SetActive(true);
        //     Weapon1ChangeBtn.SetActive(true);
        // }
        // else
        // {
        //     StartCoroutine(ShowNotEnoughGold());
        // }
    }
    
    public void Weapon1ChangeBtnClick() //무기1 교체 버튼
    {
        onWeaponChangeClicked?.Invoke();
    }
}

<스크립트가 어떻게 흘러가는지 정리>

목표는 무기를 구매하고 인벤토리에 보관하며, 보관된 무기를 강화하고, 장착하여
플레이어의 능력치에 반영하는 것.

이 모든 과정은 버튼으로 조작된다.

================
1. WeaponData (ScriptableObject)
역할: 게임에 등장하는 모든 무기의 기본 정보를 담고 있는 데이터 템플릿

  • 이름, 레벨, 스프라이트, 기본 대미지/치명타 확률, 레벨당 증가량,
    구매 비용, 최대 레벨 등 변하지 않는 고유한 스탯들을 저장
  • ScriptableObject로 만들어져 Unity 에디터에서 쉽게 새로운 무기를 생성하고 관리할 수 있음

시너지:

  • PlayerWeapon이 이 WeaponData를 참조하여 플레이어 소유 무기의 현재 상태를 관리
  • WeaponSlotUI는 이 WeaponData를 바탕으로 UI에 무기 정보를 표시
  • InventoryManager는 WeaponData를 이용하여 플레이어 인벤토리에 새로운 무기를 추가

========
2. PlayerWeapon (Serializable Class)
역할: 플레이어가 실제로 소유하고 있는 특정 무기의 '인스턴스' 데이터

  • WeaponData를 참조하고, 해당 무기의 현재 레벨(currentLevel)을 관리.
  • GetCurrentDamage(), GetCurrentCritChance() 메서드를 통해
    WeaponData의 기본 스탯과 currentLevel을 조합하여 현재 스탯을 계산.
  • WeaponLevelUp() 메서드를 통해 무기를 강화.

시너지:

  • InventoryManager는 PlayerWeapon 객체들을 리스트로 관리하여 플레이어의 인벤토리를 구성
  • EquipmentManager는 equippedWeapon 변수에 PlayerWeapon 인스턴스를 저장하여
    현재 장착된 무기를 추적
  • WeaponSlotUI는 이 PlayerWeapon의 currentLevel을 사용하여 UI에 정확한 무기 정보(레벨, 대미지, 치명타 확률)를 표시

=============
3. InventoryManager (싱글톤 MonoBehaviour)
역할: 플레이어가 획득했거나 구매한 모든 무기(PlayerWeapon 인스턴스)를
관리하는 중앙 집중형 시스템

  • playerWeapons 리스트에 PlayerWeapon 객체들을 저장하고,
    AddNewWeapon() 메서드로 새로운 무기를 추가하거나 GetPlayerWeapon()으로
    특정 무기를 찾아옴.
  • DontDestroyOnLoad를 통해 씬이 바뀌어도 인벤토리 정보가 유지.

시너지:

  • BtnClick 스크립트의 구매 버튼 로직(OnWeaponBuy)에서
    InventoryManager.Instance.AddNewWeapon()을 호출하여 무기를 구매 시 인벤토리에 추가
  • WeaponSlotUI는 InventoryManager.Instance.GetPlayerWeapon()을 통해
    해당 슬롯의 무기가 인벤토리에 있는지, 있다면 현재 레벨이 몇인지 확인하여 UI를 갱신
  • EquipmentManager는 InventoryManager에서 무기(PlayerWeapon)를 가져와 장착

=================
4. EquipmentManager (싱글톤 MonoBehaviour)
역할: 현재 플레이어에게 장착된 무기(equippedWeapon)를 관리하는 시스템

  • EquipWeapon() 메서드를 통해 특정 무기를 장착.
  • UnEquipWeapon()으로 해제.
  • OnEquipmentChanged라는 static event Action을 가지고 있어,
    무기가 장착되거나 해제될 때마다 이 이벤트를 발생시킴.
  • DontDestroyOnLoad로 씬 전환에도 장착 정보가 유지. (씬은 하나 밖에 없기는 함)

시너지:

  • WeaponSlotUI는 EquipmentManager.OnEquipmentChanged 이벤트를 구독하여,
    무기 장착 상태가 바뀔 때마다 자신의 UI를 갱신하여
    현재 장착된 무기를 표시하거나 버튼 상태를 변경 (현재 디버그가 2번씩 나오는 현상이 있음)
  • 다른 게임 시스템 (예: 플레이어 전투 로직)은 EquipmentManager.Instance.equippedWeapon을
    참조하여 플레이어의 현재 무기 공격력, 치명타 확률 등을 가져와 계산에 활용할 수 있음

=================
5. BtnClick (싱글톤 MonoBehaviour) - 팀원이 작성한 코드를 내가 일부 수정한 것
역할: 게임 내 UI 버튼의 클릭 이벤트를 중앙에서 처리하고,
해당 이벤트에 따라 관련 로직을 실행하거나 다른 스크립트의 이벤트를 발생시키는 역할

  • UnityEvent들을 통해 UI 버튼과 스크립트 로직 간의 느슨한 연결을 제공.
  • static event Action인 OnNewGameButtonClick을 통해
    씬 전환과 같은 전역적인 이벤트를 알림.

시너지:

  • WeaponSlotUI는 BtnClick.Instance의 UnityEvent들
    (onWeaponPanelClicked, onWeaponBuyClicked, onWeaponChangeClicked)을 구독하여,
    해당 버튼이 클릭될 때 자신의
    OnWeaponPanelOpened(), OnWeaponBuy(), OnWeaponChange() 메서드를 실행.

이를 통해 사용자 입력이 UI와 로직으로 전달.

=================
6. WeaponSlotUI (MonoBehaviour)
역할: 각 개별 무기 슬롯의 UI(무기 가방의 무기들)를 관리

  • WeaponData 에셋(SO)을 참조하여 해당 무기의 정보를 표시하고,
    무기 소유 여부, 현재 레벨, 장착 여부, 구매/강화/장착 버튼의 활성화 상태 등을
    UpdateWeaponSlotUI() 메서드를 통해 갱신

시너지:

  • BtnClick에서 발생시키는 이벤트들을 구독하여 자신의 무기 구매, 장착 등의 로직을 실행
  • InventoryManager에서 무기 소유 여부 및 현재 레벨을 조회하여 UI를 갱신
  • EquipmentManager의 OnEquipmentChanged 이벤트에 반응하여, 어떤 무기가 장착되었는지에 따라 자신의 장착 상태 표시 및 버튼 활성화 여부를 조정

0개의 댓글