처음 유니티를 접하고 만들었던 게임에 유니티 Ads로 수익화했었던 기억이 있습니다. 현시점 기준으로 확인해보니 전에 구현했던 방법과는 변경 점이 있었고 유니티 Document를 참고하여 정리한 유니티 Ads 구현 방법을 정리해보았습니다.
1. 프로젝트 설정
Windows > General > Services 창을 열어 프로젝트 초기 설정을 합니다.(조직 선택 및 프로젝트 ID 생성 등)
조직 선택 후 프로젝트 ID 생성 > 앱이 13 이하 어린이를 타깃으로 하는지 입력하고 저장합니다.
Ads 서비스 OFF 버튼을 토글 하여 ON으로 활성화시킵니다. 토글 직 후 유니티 Ads 패키지가 자동으로 설치됩니다.
에디터 버전 2021.3.7f1에 2022.08.31 기준으로 3.7.5 버전이 기본 설치됩니다. "Install Lastest Version"을 눌러 최신 버전인 4.3.0 버전으로 업그레이드합니다. Game Id 필드 값은 관련 코드 작성 시 요구되므로 미리 복사해두면 편합니다.
2. 테스트를 위한 UI 구성
Canvas 및에 UI 패널과 titleText 그리고 보상형 광고와 전면 광고를 실행할 RewardAdsButton, InterstitialAdsButton 2개를 생성하였습니다. 전면광고는 보통 버튼형으로 사용하지 않지만 테스트가 용이하도록 버튼형으로 구성하였습니다.
3. 스크립트 구성
공식 문서를 참고해보니 유니티 게임 서비스를 초기화하는 AdsInitializer와 각 광고에 맞게 각각 별도의 코드로 예시가 작성되어있었습니다. 기존에 사용하던 이벤트 인터페이스 IUnityAdsListener는 UnityEngine.Advertisements 네임스페이스에 존재하지 않았고 IUnityAdsInitializationListener, IUnityAdsLoadListener, IUnityAdsShowListener로 세분화되어 있습니다.
- AdsInitializer.cs (초기화 및 초기화 이벤트 인터페이스를 포함)
- InterstitialAdsButton.cs (전면 광고 및 관련 이벤트 인터페이스를 포함)
- RewardedAdsButton.cs (보상형 광고 및 관련 이벤트 인터페이스를 포함)
▶ AdsInitializer.cs
Unity Ads 초기화 기능을 하는 스크립트입니다. 테스트를 위한 각 광고의 초기 로드를 초기화 완료 콜백 함수 내에 작성하였습니다. Services-Ads창에서 확인한 GameID를 _androidGameId와 _iOSGameId에 변수에 각각 할당합니다.
using UnityEngine;
using UnityEngine.Advertisements;
public class AdsInitializer : MonoBehaviour, IUnityAdsInitializationListener
{
const string _androidGameId = "400001"; // GameId - android
const string _iOSGameId = "400002"; // GameId - iOS
[SerializeField] bool _testMode = true;
// 광고 로드를 위한 보상형 광고버튼 참조
[SerializeField] RewardedAdsButton rewardedAdsButton;
// 광고 로드를 위한 전면 광고버튼 참조
[SerializeField] InterstitialAdsButton interstitialAdsButton;
private string _gameId; // 플랫폼 확인 후 게임 ID가 저장될 변수
void Awake()
{
InitializeAds();
}
public void InitializeAds()
{
_gameId = (Application.platform == RuntimePlatform.IPhonePlayer)
? _iOSGameId
: _androidGameId;
// 플랫폼 확인후 게임 서비스 초기화 코드
// 3번째 인자는 IUnityAdsInitializationListener 입력
Advertisement.Initialize(_gameId, _testMode, this);
}
public void OnInitializationComplete()
{
// 초기화 완료 후 실행 되는 콜백
Debug.Log("Unity Ads initialization complete.");
// 각 광고의 초기 로드는 초기화 완료 후 사용해야됩니다.
rewardedAdsButton.LoadAd();
interstitialAdsButton.LoadAd();
}
public void OnInitializationFailed(UnityAdsInitializationError error, string message)
{
Debug.Log($"Unity Ads Initialization Failed: {error.ToString()} - {message}");
}
}
▶ InterstitialAdsButton.cs
LoadAd 함수는 AdsInitializer.cs의 초기화 완료 콜백에서 로드되는 함수이고 ShowAd() 함수는 광고 시작 트리거 함수입니다. 그 외의 콜백들은 주석으로 자세히 설명되어있습니다.
using UnityEngine;
using UnityEngine.Advertisements;
public class InterstitialAdsButton : MonoBehaviour, IUnityAdsLoadListener, IUnityAdsShowListener
{
//유닛 ID는 Unity Gaming Services(web) > Monetization > AdUnits 에서 생성된ID
[SerializeField] string _androidAdUnitId = "Interstitial_Android";
[SerializeField] string _iOsAdUnitId = "Interstitial_iOS";
string _adUnitId;
void Awake()
{
// Get the Ad Unit ID for the current platform:
_adUnitId = (Application.platform == RuntimePlatform.IPhonePlayer)
? _iOsAdUnitId
: _androidAdUnitId;
}
// Load content to the Ad Unit:
public void LoadAd()
{
// IMPORTANT! Only load content AFTER initialization (in this example, initialization is handled in a different script).
Debug.Log("Loading Ad: " + _adUnitId);
Advertisement.Load(_adUnitId, this);
}
// Show the loaded content in the Ad Unit:
public void ShowAd()
{
// Note that if the ad content wasn't previously loaded, this method will fail
Debug.Log("Showing Ad: " + _adUnitId);
Advertisement.Show(_adUnitId, this);
}
// Implement Load Listener and Show Listener interface methods:
public void OnUnityAdsAdLoaded(string adUnitId)
{
// Optionally execute code if the Ad Unit successfully loads content.
}
public void OnUnityAdsFailedToLoad(string adUnitId, UnityAdsLoadError error, string message)
{
Debug.Log($"Error loading Ad Unit: {adUnitId} - {error.ToString()} - {message}");
// Optionally execute code if the Ad Unit fails to load, such as attempting to try again.
}
public void OnUnityAdsShowFailure(string adUnitId, UnityAdsShowError error, string message)
{
Debug.Log($"Error showing Ad Unit {adUnitId}: {error.ToString()} - {message}");
// Optionally execute code if the Ad Unit fails to show, such as loading another ad.
}
public void OnUnityAdsShowStart(string adUnitId) { }
public void OnUnityAdsShowClick(string adUnitId) { }
public void OnUnityAdsShowComplete(string adUnitId, UnityAdsShowCompletionState showCompletionState) { }
}
▶ RewardedAdsButton.cs
광고 로드 완료 콜백 함수에서 _showAdButton 리스너에 ShowAd() 함수를 등록하고 버튼의 상호작용을 활성화합니다. ShowAd() 함수에서 버튼의 상호작용을 비활성화시킵니다. 광고 시청 완료 콜백 OnUnityAdsShowComplete에서 보상을 작성하고 광고를 다시 로드합니다.
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Advertisements;
public class RewardedAdsButton : MonoBehaviour, IUnityAdsLoadListener, IUnityAdsShowListener
{
[SerializeField] Button _showAdButton; //버튼
[SerializeField] string _androidAdUnitId = "Rewarded_Android"; //광고 ID
[SerializeField] string _iOSAdUnitId = "Rewarded_iOS"; //광고 ID
string _adUnitId = null; // This will remain null for unsupported platforms
void Awake()
{
// Get the Ad Unit ID for the current platform:
#if UNITY_IOS
_adUnitId = _iOSAdUnitId;
#elif UNITY_ANDROID
_adUnitId = _androidAdUnitId;
#endif
//Disable the button until the ad is ready to show:
_showAdButton.interactable = false;
}
// Load content to the Ad Unit:
public void LoadAd()
{
// IMPORTANT! Only load content AFTER initialization (in this example, initialization is handled in a different script).
Debug.Log("Loading Ad: " + _adUnitId);
Advertisement.Load(_adUnitId, this);
}
// If the ad successfully loads, add a listener to the button and enable it:
public void OnUnityAdsAdLoaded(string adUnitId)
{
Debug.Log("Ad Loaded: " + adUnitId);
if (adUnitId.Equals(_adUnitId))
{
// Configure the button to call the ShowAd() method when clicked:
_showAdButton.onClick.AddListener(ShowAd);
// Enable the button for users to click:
_showAdButton.interactable = true;
}
}
// Implement a method to execute when the user clicks the button:
public void ShowAd()
{
// Disable the button:
_showAdButton.interactable = false;
// Then show the ad:
Advertisement.Show(_adUnitId, this);
}
// Implement the Show Listener's OnUnityAdsShowComplete callback method to determine if the user gets a reward:
public void OnUnityAdsShowComplete(string adUnitId, UnityAdsShowCompletionState showCompletionState)
{
if (adUnitId.Equals(_adUnitId) && showCompletionState.Equals(UnityAdsShowCompletionState.COMPLETED))
{
Debug.Log("Unity Ads Rewarded Ad Completed");
// Grant a reward.
Debug.Log("이곳에 보상을 작성");
// Load another ad:
Advertisement.Load(_adUnitId, this);
}
}
// Implement Load and Show Listener error callbacks:
public void OnUnityAdsFailedToLoad(string adUnitId, UnityAdsLoadError error, string message)
{
Debug.Log($"Error loading Ad Unit {adUnitId}: {error.ToString()} - {message}");
// Use the error details to determine whether to try to load another ad.
}
public void OnUnityAdsShowFailure(string adUnitId, UnityAdsShowError error, string message)
{
Debug.Log($"Error showing Ad Unit {adUnitId}: {error.ToString()} - {message}");
// Use the error details to determine whether to try to load another ad.
}
public void OnUnityAdsShowStart(string adUnitId) { }
public void OnUnityAdsShowClick(string adUnitId) { }
void OnDestroy()
{
// Clean up the button listeners:
_showAdButton.onClick.RemoveAllListeners();
}
}
4. 에디터 설정
전면광고 버튼 및 보상형 광고 버튼 스크립트를 각 해당되는 버튼에 컴포넌트로 추가합니다.
빈 오브젝트를 생성하고 AdsInitializer.cs를 컴포넌트로 추가 및 버튼 레퍼런스 등록
InterstitialAdsButton 버튼 리스너에 ShowAd 함수를 등록합니다. 보상형 버튼은 코드에서 리스너에 추가하기 때문에 수동으로 등록하지 않습니다.
5. 실행 결과
실행 결과 정상 작동합니다. 아래는 각 코드의 유니티 가이드 원문 링크를 남겨 두었습니다.
추가로 인앱 결제 관련 설정이 궁금하다면 유니티 코드리스 인앱설정 포스팅을 참고해 주세요.
https://docs.unity.com/ads/InitializingTheUnitySDK.html
https://docs.unity.com/ads/ImplementingBasicAdsUnity.html
https://docs.unity.com/ads/ImplementingRewardedAdsUnity.html
'유니티 이야기' 카테고리의 다른 글
[Unity] 간단한 머지 게임 만들기 (1) | 2022.09.02 |
---|---|
[Unity] UI Object Drag 하는 방법 (0) | 2022.09.01 |
[Unity] 2022 Codeless 인앱 결제(IAP) Tutorial (2) (0) | 2022.08.30 |
[Unity] 2022 Codeless 인앱 결재(IAP) Tutorial (1) (0) | 2022.08.29 |
[Unity] 대량의 엑셀데이터 유니티 인스턴스로 밀어넣기 (0) | 2022.08.28 |
댓글