
Unity 프로젝트에서 광고를 시청하면 모든 스킬의 쿨타임을 초기화할 수 있는 시스템을 구현 중이었습니다. 이때 광고 버튼은 "버블 클릭 스킬"이 잠금 해제되어 레벨 1이 되었을 때만 동작해야 했습니다. 또한, 버블 클릭 스킬이 1레벨에 도달하면 잠금을 나타내는 아이콘이 사라져야 했습니다.
처음에 작성된 코드에서는 다음과 같은 문제가 있었습니다:
OnShowAdButtonClicked() 메서드가 "버블 클릭 스킬"의 레벨과 관계없이 항상 실행되었습니다.
스킬이 1레벨에 도달해도 잠금 상태를 나타내는 이미지가 제대로 사라지지 않았습니다.
원인
광고 버튼의 클릭 이벤트가 스킬의 잠금 상태(레벨 0)에서도 실행되도록 설정되어 있어, 스킬이 잠금 해제되지 않았음에도 광고를 시청할 수 있었습니다. 또한, 잠금 상태를 나타내는 이미지를 제거하는 코드가 제대로 작동하지 않아 UI 상에 오류가 발생했습니다.
광고 버튼의 조건 추가
먼저, OnShowAdButtonClicked() 메서드에 bubbleClickSkill.currentLevel > 0 조건을 추가하여 스킬이 1레벨 이상일 때만 광고 버튼이 동작하도록 수정했습니다. 이를 통해 스킬이 잠금 상태인 경우에는 광고 버튼이 비활성화되도록 설정했습니다.
잠금 이미지 비활성화
다음으로, UnlockCondition() 메서드를 수정하여 스킬이 1레벨이 되었을 때 잠금을 나타내는 이미지(LockImage)를 비활성화(SetActive(false))하도록 처리했습니다. 이를 통해 스킬이 잠금 해제되었음을 시각적으로 표현할 수 있게 되었습니다.
using GoogleMobileAds.Api;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
using System.Collections;
public class ADSkillManager : MonoBehaviour
{
public Skill[] allSkills;
public Image adCooldownFillImage; // 광고 스킬 쿨타임을 표시할 이미지
public TextMeshProUGUI adCooldownText; // 광고 스킬 쿨타임을 표시할 텍스트
public Button adButton; // 광고 버튼
public Image LockImage; //해금 이미지
public BubbleClickSkill bubbleClickSkill; // 버블 클릭 스킬
private bool adOnCooldown = false;
private float adCooldownRemaining;
private float adCooldownTime = 1800f; // 30분
void Start()
{
// 모든 스킬을 초기화합니다.
allSkills = FindObjectsOfType<Skill>();
adButton.onClick.AddListener(OnShowAdButtonClicked); // 클릭 이벤트 리스너 추가
// UnlockCondition 호출하여 초기 상태 설정
UnlockCondition();
}
public void ResetAllSkillCooldowns()
{
foreach (var skill in allSkills)
{
skill.ResetCooldown();
}
}
public void OnShowAdButtonClicked()
{
// 버블 클릭 스킬이 1레벨 이상일 때만 광고를 보여줌
if (!adOnCooldown && bubbleClickSkill.currentLevel > 0)
{
// 광고를 보고 난 후 모든 스킬의 쿨타임을 초기화하고, SkillManager의 쿨타임을 30분으로 설정합니다.
RewardedAdExample.Instance.ShowRewardedAd((Reward reward) =>
{
// 광고가 성공적으로 표시된 후 실행되는 콜백
ResetAllSkillCooldowns();
SetAdCooldown(adCooldownTime); // 광고 스킬 쿨타임을 30분으로 설정
});
}
}
private void SetAdCooldown(float cooldownTime)
{
adOnCooldown = true;
adCooldownRemaining = cooldownTime;
UpdateAdCooldownUIElements(cooldownTime, cooldownTime); // 쿨타임 시작 시 fillAmount를 0으로 설정
StartCoroutine(UpdateAdCooldownUI());
}
private IEnumerator UpdateAdCooldownUI()
{
while (adCooldownRemaining > 0)
{
adCooldownRemaining -= Time.deltaTime;
UpdateAdCooldownUIElements(adCooldownRemaining, adCooldownTime);
yield return null;
}
adOnCooldown = false;
UpdateAdCooldownUIElements(0, adCooldownTime); // 최종적으로 쿨타임이 0이 되었을 때 UI 업데이트
}
private void UpdateAdCooldownUIElements(float remainingTime, float cooldownTime)
{
if (adCooldownFillImage != null)
{
adCooldownFillImage.fillAmount = (cooldownTime - remainingTime) / cooldownTime;
}
if (adCooldownText != null)
{
int minutes = Mathf.FloorToInt(remainingTime / 60);
int seconds = Mathf.CeilToInt(remainingTime % 60);
adCooldownText.text = $"{minutes:D2}:{seconds:D2}";
}
}
private void UnlockCondition()
{
if (bubbleClickSkill.currentLevel == 1 && LockImage != null)
{
LockImage.gameObject.SetActive(false); // LockImage 비활성화
}
}
}
이번 문제 해결을 통해 조건에 따라 버튼이 활성화되도록 하고, 사용자에게 시각적인 피드백을 제공하는 방법을 학습했습니다. 이 과정에서 게임 오브젝트의 상태 관리를 보다 안전하고 효율적으로 처리하는 방법도 익힐 수 있었습니다. 앞으로도 이러한 조건 처리와 UI 업데이트에 대해 더 깊이 이해할 필요성을 느꼈습니다.