GameDevelop/Unity기초쌓기

Unity 보상형 광고(AdMob) – 광고 시청 후 앱 종료/버튼 안 눌림 오류 해결 방법

도도돋치 2025. 9. 18. 01:10
Contents 접기
728x90

문제 상황

Unity에서 Google AdMob 보상형 광고를 붙였을 때, 광고는 잘 뜨지만 이런 문제가 생겼다.

  • 광고 시청 후 앱이 강제 종료됨
  • UnityException: set_timeScale can only be called from the main thread 오류 발생
  • 광고 후 이어하기 버튼이 먹통이 됨

처음에는 Gradle, constraints, App ID 설정 문제로 삽질을 했지만, 실행 후 튕기거나 UI가 막히는 진짜 원인은 따로 있었다.

 

 

원인

광고 SDK의 콜백(ex: OnAdFullScreenContentClosed, RewardedAd.Show)은 Unity 메인 스레드가 아닌 다른 스레드에서 실행된다.

 

Unity의 모든 API (Time.timeScale, GameManager.Continue(), UIManager.CloseUI(), Instantiate, Destroy 등)는 메인 스레드에서만 호출 가능하기 때문에, 광고 콜백 안에서 직접 호출하면 UnityException이 발생한다.

 

 

잘못된 코드 예시

rewardedAd.Show((Reward reward) => {
    // 이렇게 하면 에러 발생
    GameManager.Instance.Continue();
    UIManager.Instance.CloseUI(UIName.RESULT_WINDOW);
});

 

 

해결 방법 – 플래그 방식

콜백 안에서는 플래그만 세팅하고, Unity 메인 스레드에서 돌아가는 Update()에서 실제 동작을 처리하는 방식으로 해결했다.

 
private bool rewardEarned = false;
private bool adClosed = false;

public void ShowRewardAd()
{
    if (rewardedAd != null && rewardedAd.CanShowAd())
    {
        rewardedAd.Show((Reward reward) =>
        {
            // 보상 플래그만 세팅
            rewardEarned = true;
        });
    }
}

private void Update()
{
    if (rewardEarned)
    {
        rewardEarned = false;
        GameManager.Instance.Continue(); // 메인 스레드에서 실행
    }

    if (adClosed)
    {
        adClosed = false;
        UIManager.Instance.CloseUI(UIName.RESULT_WINDOW);
    }
}
 
 

핵심 요약

  1. 광고 콜백은 Unity 메인 스레드가 아님 → Unity API 직접 호출 금지
  2. 광고 콜백에서는 플래그만 세팅
  3. Update()에서 플래그 확인 후 Unity API 실행
  4. 이렇게 하면 앱 종료, 버튼 먹통, set_timeScale 오류 모두 해결

 

마무리

처음엔 Gradle, App ID 설정 문제라고 생각했는데, 진짜 원인은 광고 콜백 스레드였다.

> 앞으로 콜백 = 플래그 세팅 / Update = 실제 실행 이 패턴만 기억하면, 광고 이어하기 구현이 훨씬 안정적으로 될 것 같다.

 

AdMob 보상형 광고는 콜백에서 직접 Unity API를 호출하지 말고, 플래그로 메인 스레드에서 처리하자

728x90