본문 바로가기
디지털노마드

[챗GPT활용개발] ChatGPT를 활용하여 AdMob 리워드 광고 추가 하기

by 인텔리노마드라이프 2024. 4. 25.
728x90

안녕하세요. 인텔리원스튜디오(IntelliOneStudio)입니다.

오늘은 ChatGPT를 활용해서 AdMob 리워드 광고 스크립터(Unity)를 만들어볼거예요. 

 

 ChatGPT 답변 내용 중 제가 별도로 표시한 파란색 내용을 기준으로 읽으시면 좀 더 이해가 쉽게 될거예요.

AdMob의 리워드 광고에 대해 알고 싶었어요

리워드 광고 기능을 만들기 전에 리워드 광고에 대해 설명을 부탁했어요.

그리고 AdMob 신청하는 방법은 따로 알려드릴께요.

[질문] 안녕 ChatGPT,  AdMob의 리워드 광고에 대해 자세히 설명해줄래?

[답변]
AdMob의 리워드 광고는 사용자가 앱 내에서 특정 액션을 수행할 때 보상을 제공하는 광고 형태입니다. 이러한 광고는 주로 모바일 게임이나 앱 내에서 사용자의 참여를 증가시키고자 할 때 사용됩니다. 리워드 광고는 사용자가 동영상 광고를 전체적으로 시청하거나 특정 광고와 상호 작용을 완료했을 때 보상을 받게 됩니다. 이 보상은 게임 내 통화, 앱 내 아이템, 추가 콘텐츠 접근 등 다양한 형태로 제공될 수 있습니다.

리워드 광고의 핵심 특징은 다음과 같습니다:

1. 사용자 동의 기반

사용자는 광고 시청을 통해 보상을 받기로 선택하는 경우가 많습니다. 이는 광고가 강제적이 아니라 사용자의 동의를 바탕으로 진행되므로 사용자 경험을 해치지 않으면서도 참여를 유도합니다.

2. 높은 참여도

리워드 광고는 일반 광고에 비해 높은 참여도와 완료율을 보입니다. 사용자가 보상을 받기 위해 광고 내용에 더 주의 깊게 집중하기 때문입니다.

3. 증가하는 수익

앱 개발자와 출판사에게 리워드 광고는 사용자의 적극적인 참여를 통해 더 많은 수익을 창출할 수 있는 기회를 제공합니다. 사용자가 광고를 완전히 시청할 때마다 수익이 발생합니다.

4. 사용자 경험 개선

리워드 광고는 사용자에게 가치를 제공함으로써 전반적인 앱 사용 경험을 개선할 수 있습니다. 사용자는 원하는 보상을 얻기 위해 광고 시청을 더 긍정적으로 받아들일 수 있습니다.

구현 방법

AdMob 리워드 광고를 앱에 통합하기 위해서는 AdMob SDK를 앱에 포함시키고, 광고 단위 ID를 설정한 후 필요한 코드를 작성해야 합니다. Google AdMob의 공식 문서는 이 과정을 자세히 안내하고 있으며, 개발자는 이를 따라 리워드 광고를 앱에 쉽게 통합할 수 있습니다.

최적화 및 성능 분석

AdMob에서는 리워드 광고의 성능을 분석하고 최적화할 수 있는 다양한 도구를 제공합니다. 이를 통해 앱 개발자는 광고 캠페인의 성공을 모니터링하고, 사용자 참여를 더욱 증가시킬 수 있는 방법을 모색할 수 있습니다.

리워드 광고는 앱 수익화 전략의 중요한 부분으로 자리 잡고 있으며, 사용자와 개발자 모두에게 이익을 제공하는 효과적인 광고 모델입니다.

 

 

수익이 생기는거네요. 빨리 만들어서 적용하고 싶어요.

 

그리고 제가 만들고 있는 게임에서 이 리워드 광고가 적합한지도 물어봤어요.

 

[질문] 안녕 ChatGPT, 내가 지금 만들고 있는 게임에 아이템이 있는데 플레이어가 이 아이템을 받기 위해 광고를 보게 하고 싶어. 이 경우에는 리워드 광고를 제공하는 게 맞니?

[답변]
네, 정확합니다. 사용자가 게임 내 아이템을 받기 위해 광고를 시청하는 방식을 도입하고 싶다면, 리워드 광고가 이상적인 선택입니다. 리워드 광고는 사용자가 광고를 시청하거나 특정 광고와의 상호작용을 완료하면 보상을 받을 수 있는 구조로 되어 있어, 게임 개발자가 게임 내 보상을 통해 사용자의 참여를 유도하고 게임 플레이를 더욱 장려할 수 있게 해줍니다.

이러한 방식은 사용자에게 추가적인 게임 내 아이템이나 혜택을 제공하는 동시에, 광고 시청을 통해 개발자가 수익을 창출할 수 있게 하는 이중의 이점을 제공합니다. 사용자는 자신이 원하는 보상을 얻기 위해 광고에 더욱 집중하게 되며, 이는 광고의 완료율과 참여도를 높이는 효과가 있습니다.

리워드 광고를 통해 사용자는 자발적으로 광고 시청을 선택하게 되므로, 강제적인 광고보다 훨씬 긍정적인 사용자 경험을 제공할 수 있습니다. 게임 내에서 특정 임무를 완료하거나 레벨업을 하기 위해 필요한 아이템을 리워드 광고를 통해 제공하면, 게임의 재미와 사용자의 만족도를 증가시킬 수 있습니다.

이 모델을 통합하기 위해서는 AdMob SDK를 게임에 포함시키고, 리워드 광고를 위한 적절한 설정과 코드 구현이 필요합니다. AdMob의 공식 문서와 개발자 가이드는 이 과정을 자세히 설명하고 있으며, 게임 개발자가 리워드 광고를 효과적으로 구현하고 최적화하는 데 도움을 줄 수 있습니다.

 

정확하다는 말에 기분이 좋네요.  이제 코드를 만들어봐요

이제 AdMob의 리워드 광고 스크립터를 만들어줘

[질문] 안녕 ChatGPT, AdMob 리워드 광고 스크립터를 만들어줄래? 그리고 아래 리워드 코드도 추가해줘

animalSpawner.UpdateScore(1000); // Update score with an additional 1000 points

[답변]
아래는 주어진 전면광고 코드를 리워드 광고를 처리하는 코드로 리워드 광고를 로드, 표시, 관리하는 데 필요한 주요 변경 사항을 적용했습니다. 또한, 리워드 받을 때 실행할 로직을 적절히 처리할 수 있도록 콜백 메소드에 보상 로직을 포함시켰습니다.

using System;
using UnityEngine;
using GoogleMobileAds.Api;

public class RewardedAdManager : MonoBehaviour
{
    public GameObject AdLoadedStatus;
    public AnimalSpawner animalSpawner; // AnimalSpawner에 대한 참조

    #if UNITY_ANDROID
    private const string _adUnitId = "ca-app-pub-xxxx";
    #elif UNITY_IPHONE
    private const string _adUnitId = "ca-app-pub-xxxx";
    #else
    private const string _adUnitId = "unused";
    #endif

    private RewardedAd _rewardedAd;

    void Start()
    {
        LoadAd();
    }

    public void LoadAd()
    {
        if (_rewardedAd != null)
        {
            _rewardedAd.Destroy();
        }

        Debug.Log("Loading rewarded ad.");
        AdRequest adRequest = new AdRequest.Builder().Build();
        RewardedAd.Load(_adUnitId, adRequest, (RewardedAd ad, LoadAdError error) =>
        {
            if (error != null)
            {
                Debug.LogError("Rewarded ad failed to load: " + error);
                return;
            }

            Debug.Log("Rewarded ad loaded.");
            _rewardedAd = ad;
            AdLoadedStatus?.SetActive(true);

            RegisterEventHandlers(ad);
        });
    }

    public void ShowAd()
    {
        if (_rewardedAd != null && _rewardedAd.CanShowAd())
        {
            Debug.Log("Showing rewarded ad.");
            _rewardedAd.Show(reward =>
            {
                Debug.Log($"Rewarded ad granted a reward: {reward.Amount} {reward.Type}");
                // 여기에 보상 로직을 추가합니다. 예: 사용자에게 1000점을 추가합니다.
                animalSpawner.UpdateScore(1000);
            });
        }
        else
        {
            Debug.LogError("Rewarded ad is not ready yet.");
        }
        AdLoadedStatus?.SetActive(false);
    }

    public void DestroyAd()
    {
        if (_rewardedAd != null)
        {
            Debug.Log("Destroying rewarded ad.");
            _rewardedAd.Destroy();
            _rewardedAd = null;
        }
        AdLoadedStatus?.SetActive(false);
    }

    private void RegisterEventHandlers(RewardedAd ad)
    {
        ad.OnAdLoaded += (sender, args) =>
        {
            Debug.Log("Rewarded ad loaded.");
            AdLoadedStatus?.SetActive(true);
        };

        ad.OnUserEarnedReward += (sender, reward) =>
        {
            Debug.Log($"User earned reward: {reward.Amount} {reward.Type}");
            // 보상 받은 후 실행할 추가 로직이 필요하다면 여기에 추가하세요.
        };

        // 기타 필요한 이벤트 핸들러를 여기에 추가하세요.
    }
}

 

 

ChatGPT가 만들어준 코드를 반영했어요.

문제가 생겼어요.

그런데 문제가 생겼어요.

ChatGPT가 만들어준 코드는 더 이상 지원하지 않는 형태의 옛날 방식이였어요. 

 

최신 정보를 주면 옛날 코드를 수정해줘요

ChatGPT를 사용하다보면 종종 이런 경우가 생겨요.

이런 문제가 생기면 최신 정보를 주고 수정을 해달라고 하면 되요. 

 

아래 최신 정보 코드는 ChatGPT가 알려준 GitHub에 있는 코드예요.

 

[질문] 안녕 ChatGPT, 아래 코드는 최신 정보로 만들어진 리워드 광고이고 이 코드를 학습해줘. 위에서 만들어준 코드를 아래 코드로 학습한 후 RewardedAdManager 클래스를 만들어줘 추가로 아래 코드도 적합한 곳에 넣어줘 
animalSpawner.UpdateScore(1000); // Update score with an additional 1000 points

public class RewardedAdController : MonoBehaviour
    {
        /// <summary>
        /// UI element activated when an ad is ready to show.
        /// </summary>
        public GameObject AdLoadedStatus;

        // These ad units are configured to always serve test ads.
#if UNITY_ANDROID
        private const string _adUnitId = "ca-app-pub-3940256099942544/5224354917";
#elif UNITY_IPHONE
        private const string _adUnitId = "ca-app-pub-3940256099942544/1712485313";
#else
        private const string _adUnitId = "unused";
#endif

        private RewardedAd _rewardedAd;

        /// <summary>
        /// Loads the ad.
        /// </summary>
        public void LoadAd()
        {
            // Clean up the old ad before loading a new one.
            if (_rewardedAd != null)
            {
                DestroyAd();
            }

            Debug.Log("Loading rewarded ad.");

            // Create our request used to load the ad.
            var adRequest = new AdRequest();

            // Send the request to load the ad.
            RewardedAd.Load(_adUnitId, adRequest, (RewardedAd ad, LoadAdError error) =>
            {
                // If the operation failed with a reason.
                if (error != null)
                {
                    Debug.LogError("Rewarded ad failed to load an ad with error : " + error);
                    return;
                }
                // If the operation failed for unknown reasons.
                // This is an unexpected error, please report this bug if it happens.
                if (ad == null)
                {
                    Debug.LogError("Unexpected error: Rewarded load event fired with null ad and null error.");
                    return;
                }

                // The operation completed successfully.
                Debug.Log("Rewarded ad loaded with response : " + ad.GetResponseInfo());
                _rewardedAd = ad;

                // Register to ad events to extend functionality.
                RegisterEventHandlers(ad);

                // Inform the UI that the ad is ready.
                AdLoadedStatus?.SetActive(true);
            });
        }

        /// <summary>
        /// Shows the ad.
        /// </summary>
        public void ShowAd()
        {
            if (_rewardedAd != null && _rewardedAd.CanShowAd())
            {
                Debug.Log("Showing rewarded ad.");
                _rewardedAd.Show((Reward reward) =>
                {
                    Debug.Log(String.Format("Rewarded ad granted a reward: {0} {1}",
                                            reward.Amount,
                                            reward.Type));
                });
            }
            else
            {
                Debug.LogError("Rewarded ad is not ready yet.");
            }

            // Inform the UI that the ad is not ready.
            AdLoadedStatus?.SetActive(false);
        }

        /// <summary>
        /// Destroys the ad.
        /// </summary>
        public void DestroyAd()
        {
            if (_rewardedAd != null)
            {
                Debug.Log("Destroying rewarded ad.");
                _rewardedAd.Destroy();
                _rewardedAd = null;
            }

            // Inform the UI that the ad is not ready.
            AdLoadedStatus?.SetActive(false);
        }

        /// <summary>
        /// Logs the ResponseInfo.
        /// </summary>
        public void LogResponseInfo()
        {
            if (_rewardedAd != null)
            {
                var responseInfo = _rewardedAd.GetResponseInfo();
                UnityEngine.Debug.Log(responseInfo);
            }
        }

        private void RegisterEventHandlers(RewardedAd ad)
        {
            // Raised when the ad is estimated to have earned money.
            ad.OnAdPaid += (AdValue adValue) =>
            {
                Debug.Log(String.Format("Rewarded ad paid {0} {1}.",
                    adValue.Value,
                    adValue.CurrencyCode));
            };
            // Raised when an impression is recorded for an ad.
            ad.OnAdImpressionRecorded += () =>
            {
                Debug.Log("Rewarded ad recorded an impression.");
            };
            // Raised when a click is recorded for an ad.
            ad.OnAdClicked += () =>
            {
                Debug.Log("Rewarded ad was clicked.");
            };
            // Raised when the ad opened full screen content.
            ad.OnAdFullScreenContentOpened += () =>
            {
                Debug.Log("Rewarded ad full screen content opened.");
            };
            // Raised when the ad closed full screen content.
            ad.OnAdFullScreenContentClosed += () =>
            {
                Debug.Log("Rewarded ad full screen content closed.");
            };
            // Raised when the ad failed to open full screen content.
            ad.OnAdFullScreenContentFailed += (AdError error) =>
            {
                Debug.LogError("Rewarded ad failed to open full screen content with error : "
                    + error);
            };
        }
    }

 

[답변]
이해했습니다. 제공해주신 최신 정보에 기반하여 RewardedAdManager 클래스를 완성하겠습니다. 이 클래스는 리워드 광고를 로드, 표시하고, 광고와 관련된 여러 이벤트를 처리합니다. 

using UnityEngine;
using GoogleMobileAds.Api;

public class RewardedAdManager : MonoBehaviour
{
    public GameObject AdLoadedStatus;

#if UNITY_ANDROID
    private const string _adUnitId = "ca-app-pub-3940256099942544/5224354917";
#elif UNITY_IPHONE
    private const string _adUnitId = "ca-app-pub-3940256099942544/1712485313";
#else
    private const string _adUnitId = "unused";
#endif

    private RewardedAd _rewardedAd;

    void Start()
    {
        MobileAds.Initialize(initStatus => {
            LoadAd();
        });
    }

    public void LoadAd()
    {
        if (_rewardedAd != null)
        {
            _rewardedAd.Destroy();
        }

        Debug.Log("Loading rewarded ad.");

        var adRequest = new AdRequest();

        RewardedAd.Load(_adUnitId, adRequest, (RewardedAd ad, LoadAdError error) =>
        {
            if (error != null)
            {
                Debug.LogError($"Rewarded ad failed to load with error: {error}");
                return;
            }
            if (ad == null)
            {
                Debug.LogError("Unexpected error: Rewarded load event fired with null ad and null error.");
                return;
            }

            Debug.Log($"Rewarded ad loaded with response: {ad.GetResponseInfo()}");
            _rewardedAd = ad;

            RegisterEventHandlers(ad);

            AdLoadedStatus?.SetActive(true);
        });
    }

    public void ShowAd()
    {
        if (_rewardedAd != null && _rewardedAd.CanShowAd())
        {
            Debug.Log("Showing rewarded ad.");
            _rewardedAd.Show(reward =>
            {
                Debug.Log($"Rewarded ad granted a reward: {reward.Amount} {reward.Type}");
                // 사용자가 리워드 광고를 시청 완료하면 1000점을 추가합니다.
                animalSpawner.UpdateScore(1000);
            });
        }
        else
        {
            Debug.LogError("Rewarded ad is not ready yet.");
        }

        AdLoadedStatus?.SetActive(false);
    }

    public void DestroyAd()
    {
        if (_rewardedAd != null)
        {
            Debug.Log("Destroying rewarded ad.");
            _rewardedAd.Destroy();
            _rewardedAd = null;
        }

        AdLoadedStatus?.SetActive(false);
    }

    public void LogResponseInfo()
    {
        if (_rewardedAd != null)
        {
            var responseInfo = _rewardedAd.GetResponseInfo();
            Debug.Log(responseInfo);
        }
    }

    private void RegisterEventHandlers(RewardedAd ad)
    {
        ad.OnAdPaid += (AdValue adValue) =>
        {
            Debug.Log($"Rewarded ad paid {adValue.Value} {adValue.CurrencyCode}.");
        };
        ad.OnAdImpressionRecorded += () =>
        {
            Debug.Log("Rewarded ad recorded an impression.");
        };
        ad.OnAdClicked += () =>
        {
            Debug.Log("Rewarded ad was clicked.");
        };
        ad.OnAdFullScreenContentOpened += () =>
        {
            Debug.Log("Rewarded ad full screen content opened.");
        };
        ad.OnAdFullScreenContentClosed += () =>
        {
            Debug.Log("Rewarded ad full screen content closed.");
            // Consider reloading the ad
            LoadAd();
        };
        ad.OnAdFullScreenContentFailed += (AdError error) =>
        {
            Debug.LogError($"Rewarded ad failed to open full screen content with error: {error}");
            // Consider reloading the ad
            LoadAd();
        };
    }
}

 

 

이제 정상적으로 코드가 동작하네요.

이 코드를 만들기 위해 ChatGPT와 다음의 대화도 나눴어요.

 

[질문] 안녕 ChatGPT, 궁금한 점이 있어.  내가 여러 번 최신 정보 코드를 줬는데 잘못된 답변을 여러 번 하는 이유가 뭐였니? 너도 고집이 있니?

 

[답변]
제가 여러 차례 잘못된 답변을 한 것은 당신의 지시를 정확히 이해하지 못했거나, 제가 가지고 있는 정보와 최신 정보 간의 차이를 제대로 인지하지 못했기 때문일 수 있습니다. 때로는 제가 정보를 처리하거나 전달하는 과정에서 실수를 할 수도 있고, 특히 복잡한 코드 관련 요청에서는 더욱 세심한 주의가 필요합니다. 제가 제공한 정보가 최신 상태와 일치하지 않았거나, 요구사항을 정확히 파악하지 못한 점에 대해 사과드립니다. 앞으로는 더욱 주의 깊게 당신의 요청을 처리하고, 정확한 정보를 제공하기 위해 노력하겠습니다.

 

좀 더 정확한 질문이 원하는 결과를 쉽게 만들어요

아래 질문과 같이 틀린 부분을 정확히 지적해주는 게 ChatGPT가 정확한 답을 내는 데 도움을 주는 것 같아요.

니가 만들어준 코드를 천천히 살펴봐. 너는 자꾸 (sender, adValue) 를 사용하는데 이 코드가 아니라 (AdValue adValue) 이고 각 함수마다 전달되믄 변수들이 내가 제공해준 코드와 달라. 다시 수정해줘

 

리워드 광고를 호출하고 싶은 곳에 아래 코드를 추가하면 되요.

rewardedAdManager.OnItemClicked();

 

    private void AttemptToShowAd()
    {
        if (rewardedAdManager == null)
        {
            Debug.LogError("rewardedAdManager is not initialized.");
            return;
        }

        if (AdCooldownManager.Instance.IsAdCooldownComplete())
        {
            // 광고 시청 가능
            rewardedAdManager.OnItemClicked();
        }
        else
        {
            // 여기에는 광고 시청 불가능 상태일 때의 로직을 구현하실 수 있습니다.
            Debug.Log("Ad cooldown not finished.");
        }
    }

 

 

참고로 아래 대화도 참고하세요.

[질문] 안녕 ChatGPT, 리워드 광고 테스트 ID를 알려줄래

 

[답변]

리워드 광고를 테스트하기 위한 Google AdMob의 공식 테스트 광고 단위 ID는 다음과 같습니다:

Android용 리워드 광고 테스트 ID

ca-app-pub-3940256099942544/5224354917

iOS용 리워드 광고 테스트 ID

ca-app-pub-3940256099942544/1712485313


이 테스트 광고 단위 ID들은 앱 개발과 테스트 단계에서 사용할 수 있으며, 실제 광고와 같은 방식으로 작동하지만, 실제 수익을 생성하지는 않습니다. 개발 중에는 이러한 테스트 ID를 사용하여 광고 통합을 안전하게 테스트하고, 실제 앱 출시 전에는 반드시 실제 광고 단위 ID로 교체(*아주 중요한 내용이예요)해야 합니다.

 

 

오늘은 AdMob 리워드 광고에 대해 살펴봤고,

이번 시간에 만들어본 AdMob 클래스를 이용하면 앱에 쉽게 적용할 수 있어요.  

 

앱을 만드는 기쁨도 좋지만 기쁨을 가지고 만든 앱이 돈도 벌어주면 더 기쁘겠죠?

즐거운 하루되세요.

 

[인텔리노마드라이프와 함께 행복하세요 from IntelliOneStudio]

 

지금까지,

언제나 성장하는 인텔리원스튜디오(IntelliOneStudio)입니다.

감사합니다.

728x90