업그레이드 데이터 입력 로직 및 기능 추가

캐릭터 스탯을 PlayerStats 컴포넌트에서 모아서 관리하도록 변경
코드에서도 마찬가지
This commit is contained in:
2026-02-23 00:21:44 +09:00
parent b34254137f
commit cc475bce3e
54 changed files with 1402 additions and 98 deletions

View File

@@ -0,0 +1,269 @@
using System;
using System.Collections.Generic;
using Unity.Netcode;
using UnityEngine;
using Northbound.Data;
namespace Northbound
{
/// <summary>
/// 플레이어별 업그레이드 보유 상태를 관리하는 컴포넌트
/// </summary>
public class PlayerUpgradeManager : NetworkBehaviour
{
// 보유한 업그레이드 ID 목록 (네트워크 동기화)
private NetworkList<int> _ownedUpgradeIds;
// 이벤트
public event Action<int> OnUpgradePurchased; // upgradeId
private NetworkPlayerController _networkPlayerController;
public new bool IsLocalPlayer => _networkPlayerController != null && _networkPlayerController.IsLocalPlayer;
public ulong OwnerPlayerId => _networkPlayerController != null ? _networkPlayerController.OwnerPlayerId : OwnerClientId;
private void Awake()
{
_ownedUpgradeIds = new NetworkList<int>();
_networkPlayerController = GetComponent<NetworkPlayerController>();
}
public override void OnNetworkSpawn()
{
base.OnNetworkSpawn();
if (_networkPlayerController != null)
{
_networkPlayerController.OnOwnerChanged += OnOwnerChanged;
}
}
public override void OnNetworkDespawn()
{
base.OnNetworkDespawn();
if (_networkPlayerController != null)
{
_networkPlayerController.OnOwnerChanged -= OnOwnerChanged;
}
_ownedUpgradeIds.Dispose();
}
private void OnOwnerChanged(ulong newOwnerId)
{
// 소유자 변경 시 필요한 처리
}
/// <summary>
/// 보유한 업그레이드 ID 목록 (복사본 반환)
/// </summary>
public List<int> GetOwnedUpgradeIdList()
{
var list = new List<int>();
foreach (int id in _ownedUpgradeIds)
{
list.Add(id);
}
return list;
}
/// <summary>
/// 특정 업그레이드를 보유하고 있는지 확인
/// </summary>
public bool HasUpgrade(int upgradeId)
{
foreach (int id in _ownedUpgradeIds)
{
if (id == upgradeId)
return true;
}
return false;
}
/// <summary>
/// 보유한 업그레이드 ID를 HashSet으로 반환
/// </summary>
public HashSet<int> GetOwnedUpgradeIdSet()
{
var set = new HashSet<int>();
foreach (int id in _ownedUpgradeIds)
{
set.Add(id);
}
return set;
}
/// <summary>
/// 업그레이드 구매 요청 (클라이언트에서 호출)
/// </summary>
public void RequestPurchaseUpgrade(int upgradeId)
{
PurchaseUpgradeServerRpc(upgradeId);
}
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
private void PurchaseUpgradeServerRpc(int upgradeId)
{
if (!CanPurchaseUpgrade(upgradeId, out string failReason))
{
Debug.LogWarning($"[PlayerUpgradeManager] 업그레이드 구매 실패: {failReason}");
return;
}
// 업그레이드 데이터 가져오기
var upgrade = UpgradeDatabase.Instance?.GetUpgradeById(upgradeId);
if (upgrade == null)
{
Debug.LogError($"[PlayerUpgradeManager] 업그레이드 ID {upgradeId}를 찾을 수 없습니다.");
return;
}
// 비용 차감
var core = CoreResourceManager.Instance?.mainCore;
if (core == null)
{
Debug.LogError("[PlayerUpgradeManager] 코어를 찾을 수 없습니다.");
return;
}
if (!core.CanConsumeResource(upgrade.mana))
{
Debug.LogWarning($"[PlayerUpgradeManager] 자원이 부족합니다. 필요: {upgrade.mana}");
return;
}
core.ConsumeResourceServerRpc(upgrade.mana);
// 업그레이드 추가
_ownedUpgradeIds.Add(upgradeId);
Debug.Log($"<color=green>[PlayerUpgradeManager] 업그레이드 '{upgrade.memo}' 구매 완료! (ID: {upgradeId})</color>");
// 이벤트 발생
OnUpgradePurchased?.Invoke(upgradeId);
}
/// <summary>
/// 업그레이드 구매 가능 여부 확인
/// </summary>
private bool CanPurchaseUpgrade(int upgradeId, out string failReason)
{
failReason = string.Empty;
var upgradeDatabase = UpgradeDatabase.Instance;
if (upgradeDatabase == null)
{
failReason = "UpgradeDatabase가 초기화되지 않았습니다.";
return false;
}
var upgrade = upgradeDatabase.GetUpgradeById(upgradeId);
if (upgrade == null)
{
failReason = $"업그레이드 ID {upgradeId}를 찾을 수 없습니다.";
return false;
}
// 이미 보유 중인지 확인
if (HasUpgrade(upgradeId))
{
failReason = "이미 보유한 업그레이드입니다.";
return false;
}
// 선행 조건 확인
if (!upgradeDatabase.ArePrerequisitesMet(upgradeId, GetOwnedUpgradeIdSet()))
{
failReason = "선행 업그레이드 조건을 충족하지 않았습니다.";
return false;
}
// 비용 확인
var core = CoreResourceManager.Instance?.mainCore;
if (core == null)
{
failReason = "코어를 찾을 수 없습니다.";
return false;
}
if (!core.CanConsumeResource(upgrade.mana))
{
failReason = $"자원이 부족합니다. 필요: {upgrade.mana}, 보유: {core.TotalResources}";
return false;
}
// 개인 업그레이드인지 확인
if (upgrade.upgradeTarget != "person")
{
failReason = "팀 업그레이드는 개인이 구매할 수 없습니다.";
return false;
}
return true;
}
/// <summary>
/// 업그레이드 구매 가능 여부 (외부용)
/// </summary>
public bool CanPurchase(int upgradeId)
{
return CanPurchaseUpgrade(upgradeId, out _);
}
/// <summary>
/// 구매 가능한 업그레이드 목록 반환
/// </summary>
public List<UpgradeData> GetPurchasableUpgrades()
{
var result = new List<UpgradeData>();
var upgradeDatabase = UpgradeDatabase.Instance;
if (upgradeDatabase == null) return result;
var personalUpgrades = upgradeDatabase.GetPersonalUpgrades();
var ownedIds = GetOwnedUpgradeIdSet();
foreach (var upgrade in personalUpgrades)
{
if (upgrade == null) continue;
// 이미 보유하면 제외
if (ownedIds.Contains(upgrade.id)) continue;
// 선행 조건 충족 시 구매 가능
if (upgradeDatabase.ArePrerequisitesMet(upgrade.id, ownedIds))
{
result.Add(upgrade);
}
}
return result;
}
/// <summary>
/// 보유한 업그레이드 데이터 목록 반환
/// </summary>
public List<UpgradeData> GetOwnedUpgradeData()
{
var result = new List<UpgradeData>();
var upgradeDatabase = UpgradeDatabase.Instance;
if (upgradeDatabase == null) return result;
foreach (int id in _ownedUpgradeIds)
{
var upgrade = upgradeDatabase.GetUpgradeById(id);
if (upgrade != null)
{
result.Add(upgrade);
}
}
return result;
}
}
}