유니티 플레이팹 가상화폐 돈 증가 감소 간단 구현 Unity Playfab

반응형

유니티 플레이팹 가상화폐 돈 증가 감소 간단 구현 Unity Playfab

코드 작성

using System;
using System.Collections.Generic;
using PlayFab;
using PlayFab.ClientModels;
using UnityEngine;

// 화폐 타입 열거형
public enum MoneyType
{
    Gold,
    Crystal
}

public partial class PlayfabManager : MonoBehaviour
{
    // 현재 보유 화폐량
    private int gold = 0;
    private int crystal = 0;
    
    // 가상 화폐 코드 매핑
    private readonly Dictionary<MoneyType, string> currencyCodes = new Dictionary<MoneyType, string>
    {
        { MoneyType.Gold, "GO" },
        { MoneyType.Crystal, "CR" }
    };
    
    // 이벤트 시스템
    public event Action<MoneyType, int, int> OnCurrencyUpdated; // 화폐 타입, 변화량, 현재량
    public event Action<PlayFabError> OnCurrencyUpdateFailed;
    
    // 프로퍼티
    public int Gold => gold;
    public int Crystal => crystal;
    
    // 화폐 증가 함수
    public void UpdateAddCurrency(MoneyType moneyType, int amount)
    {
        // 유효성 검사
        if (amount <= 0)
        {
            Debug.LogError($"화폐 증가 실패: 금액은 양수여야 합니다. (요청 금액: {amount})");
            OnCurrencyUpdateFailed?.Invoke(new PlayFabError 
            { 
                Error = PlayFabErrorCode.InvalidParams,
                ErrorMessage = "금액은 양수여야 합니다."
            });
            return;
        }
        
        // 화폐 코드 가져오기
        if (!currencyCodes.TryGetValue(moneyType, out string currencyCode))
        {
            Debug.LogError($"화폐 증가 실패: 알 수 없는 화폐 타입 - {moneyType}");
            OnCurrencyUpdateFailed?.Invoke(new PlayFabError 
            { 
                Error = PlayFabErrorCode.InvalidParams,
                ErrorMessage = "알 수 없는 화폐 타입"
            });
            return;
        }
        
        Debug.Log($"{GetMoneyTypeName(moneyType)} {amount} 증가 요청 중...");
        
        var request = new AddUserVirtualCurrencyRequest
        {
            VirtualCurrency = currencyCode,
            Amount = amount
        };
        
        PlayFabClientAPI.AddUserVirtualCurrency(request, 
            result => {
                // 로컬 변수 업데이트
                UpdateLocalCurrency(moneyType, result.Balance);
                
                Debug.Log($"{GetMoneyTypeName(moneyType)} {amount} 증가 완료. 현재 잔액: {result.Balance}");
                
                // 이벤트 호출
                OnCurrencyUpdated?.Invoke(moneyType, amount, result.Balance);
            }, 
            error => {
                Debug.LogError($"화폐 증가 실패: {error.ErrorMessage}");
                OnCurrencyUpdateFailed?.Invoke(error);
            });
    }
    
    // 화폐 감소 함수
    public void UpdateSubtractCurrency(MoneyType moneyType, int amount)
    {
        // 유효성 검사
        if (amount <= 0)
        {
            Debug.LogError($"화폐 감소 실패: 금액은 양수여야 합니다. (요청 금액: {amount})");
            OnCurrencyUpdateFailed?.Invoke(new PlayFabError 
            { 
                Error = PlayFabErrorCode.InvalidParams,
                ErrorMessage = "금액은 양수여야 합니다."
            });
            return;
        }
        
        // 화폐 코드 가져오기
        if (!currencyCodes.TryGetValue(moneyType, out string currencyCode))
        {
            Debug.LogError($"화폐 감소 실패: 알 수 없는 화폐 타입 - {moneyType}");
            OnCurrencyUpdateFailed?.Invoke(new PlayFabError 
            { 
                Error = PlayFabErrorCode.InvalidParams,
                ErrorMessage = "알 수 없는 화폐 타입"
            });
            return;
        }
        
        // 현재 잔액 확인 (로컬)
        int currentBalance = GetLocalCurrencyBalance(moneyType);
        if (currentBalance < amount)
        {
            Debug.LogWarning($"화폐 감소 요청: 잔액 부족 가능성 (현재: {currentBalance}, 요청: {amount})");
        }
        
        Debug.Log($"{GetMoneyTypeName(moneyType)} {amount} 감소 요청 중...");
        
        var request = new SubtractUserVirtualCurrencyRequest
        {
            VirtualCurrency = currencyCode,
            Amount = amount
        };
        
        PlayFabClientAPI.SubtractUserVirtualCurrency(request, 
            result => {
                // 로컬 변수 업데이트
                UpdateLocalCurrency(moneyType, result.Balance);
                
                Debug.Log($"{GetMoneyTypeName(moneyType)} {amount} 감소 완료. 현재 잔액: {result.Balance}");
                
                // 이벤트 호출
                OnCurrencyUpdated?.Invoke(moneyType, -amount, result.Balance);
            }, 
            error => {
                if (error.Error == PlayFabErrorCode.InsufficientFunds)
                {
                    Debug.LogError($"화폐 감소 실패: 잔액이 부족합니다.");
                }
                else
                {
                    Debug.LogError($"화폐 감소 실패: {error.ErrorMessage}");
                }
                
                OnCurrencyUpdateFailed?.Invoke(error);
            });
    }
    
    // 가상 화폐 잔액 조회
    public void GetVirtualCurrencyBalance()
    {
        PlayFabClientAPI.GetUserInventory(new GetUserInventoryRequest(),
            result => {
                Debug.Log("가상 화폐 잔액 조회 완료");
                
                if (result.VirtualCurrency != null)
                {
                    foreach (var currency in result.VirtualCurrency)
                    {
                        Debug.Log($"화폐: {currency.Key}, 잔액: {currency.Value}");
                        
                        // 로컬 변수 업데이트
                        if (currency.Key == "GO")
                        {
                            UpdateLocalCurrency(MoneyType.Gold, currency.Value);
                        }
                        else if (currency.Key == "CR")
                        {
                            UpdateLocalCurrency(MoneyType.Crystal, currency.Value);
                        }
                    }
                }
            },
            error => {
                Debug.LogError($"가상 화폐 잔액 조회 실패: {error.ErrorMessage}");
            });
    }
    
    // 로컬 화폐 값 업데이트
    private void UpdateLocalCurrency(MoneyType moneyType, int balance)
    {
        switch (moneyType)
        {
            case MoneyType.Gold:
                gold = balance;
                break;
            case MoneyType.Crystal:
                crystal = balance;
                break;
        }
    }
    
    // 로컬 화폐 잔액 조회
    private int GetLocalCurrencyBalance(MoneyType moneyType)
    {
        switch (moneyType)
        {
            case MoneyType.Gold:
                return gold;
            case MoneyType.Crystal:
                return crystal;
            default:
                return 0;
        }
    }
    
    // 화폐 타입 이름 반환
    private string GetMoneyTypeName(MoneyType moneyType)
    {
        switch (moneyType)
        {
            case MoneyType.Gold:
                return "골드";
            case MoneyType.Crystal:
                return "크리스탈";
            default:
                return "알 수 없음";
        }
    }
}

 

반응형