-
Notifications
You must be signed in to change notification settings - Fork 0
Purchasing integration (Android)
유니티는 사용자가 Unity IAP를 구현하지 않고도 최적화된 수익화 기능을 활용할 수 있도록 지원합니다. 다음의 기초적인 단계들을 따라 자체적인 인앱 구매 솔루션을 유지하면서 동시에 Unity Ads 3.0+으로 IAP Promo를 생성하고 개인화 플레이스먼트를 활용해 보세요.
- 프로젝트에 Unity Ads SDK 3.0+을 설치합니다.
- Developer Dashboard에서 수동으로 제품 카탈로그를 구성합니다.
- 대시보드에서 IAP Promo를 구성합니다.
-
UnityMonetization
API를 사용하여 게임 코드에서 구매 어댑터를 구현합니다. - 구매 어댑터 내에서 게임 로직 및 구매 이벤트를 구현합니다.
- 구매 어댑터와 수익화 SDK를 초기화합니다.
다음은 Java를 사용하는 Android 개발자를 위한 지침입니다.
여기에서 Unity Ads 프레임워크 unity-ads.aar 을 다운로드하십시오. UnityMonetization
API는 SDK 3.0 이상 버전이 필요합니다.
- Android Studio에서 기존 Android 프로젝트를 열거나 새로 생성합니다.
- 새로운 모듈을 추가하고 unity-ads.aar 파일을 임포트합니다. “unity-ads" 등 모듈의 이름을 지정합니다.
- 프로젝트 화면에서 모듈을 오른쪽 클릭한 다음 Open Module Settings > app을 선택하고 "unity-ads" 모듈을 종속 관계(dependency)로 추가합니다.
- Java Activity 파일에 다음 임포트 구문을 추가합니다.
import com.unity3d.services.IUnityServicesListener;
import com.unity3d.services.monetization.UnityMonetization;
빌드 시스템에서 .aar 패키지를 사용할 수 없는 경우에도 유니티는 GitHub에 동일한 리소스를 ZIP 형태의 unity-ads.zip 파일로 제공합니다. Unity Ads를 사용하려면 다음 단계를 따르십시오.
- 빌드에 classes.jar 를 포함합니다.
-
AndroidManifest.xml 로부터 매니페스트를 수동으로 병합합니다.
AdUnitActivity
와AdUnitSoftwareActivity
activity가 모두 포함되었는지 확인합니다. 또한INTERNET
및ACCESS_NETWORK_STATE
권한도 추가해야 합니다. - ProGuard를 사용한다면, ProGuard 구성에 proguard.txt 의 모든 행을 추가합니다.
구매 어댑터를 구현하기 전에 Operate 탭(Developer Dashboard)으로 이동한 다음 제품 카탈로그 완성을 위한 수동 구성 지침을 따르십시오.
Operate 탭(Developer Dashboard)에서, IAP Promo 구성 지침을 따르십시오.
게임 스크립트에서 com.unity3d.services.purchasing.core.IPurchasingAdapter
인터페이스를 포함한 뒤에 구매 어댑터를 구현하는 클래스를 생성할 수 있습니다. 두 가지 함수, retrieveProducts
및 onPurchase
를 사용하여 구매 어댑터에서 사용할 게임 로직을 정의할 수 있습니다. 이들 메서드는 IPurchasingAdapter
를 사용하는 클래스가 필요합니다. SDK가 제품 거래를 관리할 때 필요에 맞게 호출하려면 이를 구현해야 합니다.
import com.unity3d.services.purchasing.core.IPurchasingAdapter;
private class UnityPurchasingAdapter implements IPurchasingAdapter {
// Placeholder for retrieveProducts function
// Placeholder for onPurchase function
}
Product Catalog 가져오기
SDK는 retrieveProducts
를 호출하여 이용할 수 있는 제품의 목록을 가져옵니다. 함수는 IAP 제품을 UnityMonetization.Product
오브젝트로 전환해야 합니다. 각 제품마다 최소 productID
, localizedPriceString
, productType
, isoCurrencyCode
및 localizedTitle
문자열이 필요합니다.
이 함수는 IRetrieveProductsListener
리스너를 받습니다. 리스너의 onProductsRetrieved
함수를 호출하여 가져온 제품 목록을 SDK로 전송합니다.
구매 처리
사용자가 프로모션 에셋의 구매하기 버튼을 클릭하면 SDK는 onPurchase
를 호출합니다. 구매 성공 또는 실패 핸들링은 인앱 구매 구현 방식에 따라 달라집니다.
거래가 성공하면 TransactionDetails
오브젝트를 사용하여 리스너의 onTransactionComplete
함수를 호출합니다.
거래가 실패하면 TransactionError
오브젝트를 사용하여 리스너의 onTransactionError
함수를 호출합니다.
IPurchasingAdapter
구현 예제
import com.unity3d.services.purchasing.core.IPurchasingAdapter;
private class UnityPurchasingAdapter implements IPurchasingAdapter {
@Override
public void retrieveProducts (IRetrieveProductsListener listener) {
// Query your Products here, convert them to Monetization.Products, then populate the Product list with them:
listener.onProductsRetrieved (Arrays.asList (Product.newBuilder ()
.withProductId ("100bronzeCoins")
.withLocalizedTitle ("100 Bronze Coins")
.withLocalizedPriceString ("$1.99")
.withIsoCurrencyCode ("USD")
.withProductType ("Consumable")
.build ()));
}
@Override
public void onPurchase (String productID, ITransactionListener listener, Map<String, Object> extras) {
thirdPartyPurchasing.purchase (productId); // Generic third-party purchasing function
// If purchase succeeds:
listener.onTransactionComplete (TransactionDetails.newBuilder ()
.withTransactionId ("ABCDE")
.withReceipt ("Parsed receipt string here")
.build ());
// If purchase fails:
listener.onTransactionError (TransactionErrorDetails.newBuilder ()
.withTransactionError (TransactionError.NETWORK_ERROR)
.withExceptionMessage ("Example: network connection dropped")
.withStore (Store.GOOGLE_PLAY)
.withStoreSpecificErrorCode ("Example: Google Play lost network connection")
.build ());
}
}
}
구매 어댑터를 구현했다면 setAdapter
메서드를 사용하여 레퍼런스를 제공해야 합니다. 마지막으로, 해당 플랫폼에서 프로젝트의 게임 ID를 이용하여 SDK를 초기화해야 합니다. ID는 Developer Dashboard의 Operate 탭에서 프로젝트를 선택한 다음, 왼쪽 내비게이션에서 Monetization > Platforms를 선택하여 찾을 수 있습니다.
오류를 방지하려면 게임 런타임 수명주기에서 최대한 이른 시점에 이 호출을 구현하는 것이 좋습니다. 예를 들면 다음과 같습니다.
@Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
UnityPurchasing.setAdapter (new UnityPurchasingAdapter ());
UnityServices.initialize (this, unityGameID, this);
}
구매 어댑터를 관리하는 정적인 클래스이며 SDK가 커스텀 IAP 구현으로부터 정보를 가져올 때 필요로 하는 인터페이스입니다. Unity Ads SDK 3.0+를 설치하고 com.unity3d.services.purchasing.core.IPurchasingAdapter interface
를 포함시켜 필요한 API에 액세스하십시오.
public class UnityPurchasing {
public static void setAdapter (IPurchasingAdapter adapter);
public static IPurchasingAdapter getAdapter ();
}
구현하여 SDK에 다시 전달하는 어댑터입니다.
public interface IPurchasingAdapter {
void retrieveProducts (IRetrieveProductsListener listener);
void onPurchase (String productID, ITransactionListener listener, Map<String, Object> extras);
}
SDK는 이를 호출하여 이용할 수 있는 제품의 목록을 가져옵니다.
void retrieveProducts (IRetrieveProductsListener listener);
IRetrieveProductsListener
를 사용하여 제품 목록을 등록할 수 있습니다.
IRetrieveProductsListener
IPurchasingAdapter
를 통해서 SDK가 다시 전달하는 오브젝트의 인터페이스입니다.
public interface IRetrieveProductsListener {
void onProductsRetrieved (List<Product> availableProducts);
}
SDK로 IAP 제품을 등록합니다. IAP 제품을 UnityMonetization.Product
오브젝트로 전환하도록 구현해야 합니다. 각 제품마다 최소 productID
, localizedPriceString
, productType
, isoCurrencyCode
및 localizedTitle
문자열이 필요합니다. 제품 프로퍼티에 대한 자세한 내용은 아래 섹션의 제품 클래스 세부 내용을 참조하세요.
retrieveProducts
함수를 구현한 아래 예제를 참조하시기 바랍니다.
@Override
public void retrieveProducts (IRetrieveProductsListener listener) {
listener.onProductsRetrieved (Arrays.asList (Product.newBuilder ()
.withProductId ("100BronzeCoins")
.withLocalizedTitle ("100 Bronze Coins")
.withLocalizedPriceString ("$1.99")
.withLocalizedPrice (1.99)
.withIsoCurrencyCode ("USD")
.withLocalizedDescription ("100 Bronze Coins at a new low price!")
.withProductType ("Consumable")
.build ()));
}
Product
SDK가 수익화를 최적화하는 데 사용하는 오브젝트로 전환된 IAP 제품입니다.
public static Builder newBuilder()
메서드를 사용하여 빌더에 다음 필드를 설정한 다음 public Product build()
메서드를 사용하여 최종 제품 오브젝트를 구성합니다.
빌더 메서드 | 파라미터 유형 | 설명 |
---|---|---|
withProductId |
String |
제품의 내부 레퍼런스 ID입니다. |
withLocalizedTitle |
String |
소비자가 스토어 UI에서 보는 제품 이름입니다. |
withLocalizedPriceString |
String |
소비자가 스토어 UI에서 보는 가격 문자열이며 화폐 기호가 포함됩니다. |
withLocalizedPrice |
Double |
제품 가격의 내부 시스템 값입니다. |
withIsoCurrencyCode |
String |
제품의 현지 화폐의 ISO 코드입니다. |
withLocalizedDescription |
String |
소비자가 스토어 UI에서 보는 제품 설명입니다. |
withProductType |
String |
Unity는 “Consumable(소모품)”과 “Non-Consumable(비소모품)”, 그리고 “Subscription(구독)” 제품 유형을 지원합니다. |
다음 함수를 이용하여 제품 프로퍼티를 가져올 수 있습니다.
public String getProductId ();
public String getLocalizedTitle ();
public String getLocalizedPriceString ();
public double getLocalizedPrice ();
public String getIsoCurrencyCode ();
public String getLocalizedDescription ();
public String getProductType ();
제품 프로퍼티에 대한 자세한 내용은 제품 정의 참고 문서를 참조하세요.
사용자가 프로모션 에셋의 구매하기 버튼을 클릭하면 SDK는 이 함수를 호출합니다. Unity는 구매된 제품의 ID를 인앱 구매 시스템에 전달합니다. 구매 성공 또는 실패 핸들링은 인앱 구매 구현 방식에 따라 달라집니다.
public void onPurchase (String productID, ITransactionListener listener, Map<String, Object> extras)
ITransactionListener
IPurchasingAdapter
를 통해서 SDK가 다시 전달하는 오브젝트의 인터페이스입니다.
public interface ITransactionListener {
void onTransactionComplete (TransactionDetails details);
void onTransactionError (TransactionError error, String message);
}
성공적으로 완료되는 거래를 핸들링하는 커스텀 게임 로직입니다. 함수는 거래의 세부 내용을 설명하는 TransactionDetails
오브젝트를 받습니다.
실패한 거래를 핸들링하는 커스텀 게임 로직입니다. 함수는 거래 실패의 소스를 식별하는 TransactionError
오브젝트를 받습니다.
onPurchase
구현 예제
@Override
public void onPurchase (String productID, ITransactionListener listener, Map<String, Object> extras) {
thirdPartyPurchasing.purchase (productId); // Generic developer purchasing function
// If purchase succeeds:
listener.onTransactionComplete (TransactionDetails.newBuilder ()
.withProductId ("100BronzeCoins")
.withTransactionId ("ABCDEFG")
.withReceipt ("receipt":"{\"data\": \"{\"Store\": \"fake\", \"TransactionID\": \"ce7bb1ca-bd34-4ffb-bdee-83d2784336d8\", \"Payload\": \"{ \\\"this\\\": \\\"is a fake receipt\\\"}\"}\"}")
.withPrice (1.99)
.withIsoCurrency ("USD")
.build());
// If purchase fails:
listener.onTransactionError (TransactionError.NETWORK_ERROR, "No Network Connection");
}
TransactionDetails
SDK가 수익화를 최적화하는 데 사용하는 오브젝트로 전환된 IAP 거래 영수기록입니다.
public static Builder newBuilder()
메서드를 사용하여 빌더에 다음 필드를 설정한 다음 public TransactionDetails build()
메서드를 사용하여 최종 제품 오브젝트를 구성합니다.
빌더 메서드 | 파라미터 유형 | 설명 |
---|---|---|
withProductId |
String |
제품의 내부 레퍼런스 ID입니다. |
withTransactionId |
String |
거래에 대한 내부 레퍼런스 ID입니다. |
withReceipt |
String |
거래의 세부 내용을 다루는 INAPP_PURCHASE_DATA 의 JSON 필드입니다. Store, TransactionID 및 Payload를 포함하는 JSON 오브젝트로 영수기록을 인코딩합니다. |
withPrice |
BigDecimal |
제품 가격의 내부 시스템 값입니다. |
withIsoCurrency |
String |
제품의 현지 화폐의 ISO 코드입니다. |
다음 함수를 이용하여 제품 프로퍼티를 가져올 수 있습니다.
public String getProductId ();
public String getTransactionId ();
public String getReceipt ();
public BigDecimal getPrice ();
public String getCurrency ();
TransactionError
거래 실패 사유를 나타내는 열거형입니다.
public enum TransactionError {
ITEM_UNAVAILABLE
NETWORK_ERROR
NOT_SUPPORTED
SERVER_ERROR
UNKNOWN_ERROR
USER_CANCELLED
}
SDK는 수익화 최적화를 지원하기 위해 비Unity 개발자에게 Unity Analytics API를 제공합니다. 다음 분석 이벤트를 구현하여 다시 SDK로 보내면 게임의 경제를 심층적으로 분석할 수 있습니다. SDK가 플레이어의 동작에 대해서 더 많은 정보를 파악할수록 수익화 전략을 더 효과적으로 관리할 수 있습니다.
public class UnityAnalytics { }
플레이어가 게임 내 리소스를 확보할 때 이 이벤트를 호출합니다.
public static void onItemAcquired (String transactionContext, Float amount, String itemId, Float balance, String itemType, String level, String transactionId, AcquisitionType acquisitionType);
플레이어가 게임 내 리소스를 소모할 때 이 이벤트를 호출합니다.
public static void onItemSpent (String transactionContext, Float amount, String itemId, Float balance, String itemType, String level, String transactionId, AcquisitionType acquisitionType);
프로퍼티 | 유형 | 설명 |
---|---|---|
transactionContext |
String |
거래를 위한 게임 내 컨텍스트의 설명입니다(예: 전리품 상자). |
amount |
Float |
획득한 리소스의 수량입니다. |
itemId |
String |
획득한 리소스에 대한 내부 레퍼런스 ID입니다. |
balance |
Float |
플레이어가 획득한 리소스의 새로운(거래 후) 수량입니다. |
itemType |
String |
획득한 리소스의 범주입니다(예: “Premium currency”). |
level |
String |
플레이어가 리소스를 획득한 레벨/지역의 이름 또는 ID입니다(예: 1레벨 스토어). |
transactionId |
String |
거래에 대한 내부 레퍼런스 ID입니다. 원하는 바에 따라 이러한 식별자를 활용하여 다수의 이벤트를 하나의 거래로 그룹화할 수 있습니다. |
acquisitionType |
AcquisitionType |
게임 내 화폐(Soft Currency) 또는 프리미엄 화폐(Premium Currency)를 나타냅니다(아래 섹션 참조). |
이 이벤트는 SDK가 Promo를 표시할 최적의 시점을 인지하도록 교육하고 지원합니다. 다음 예제를 한 번 살펴보도록 하겠습니다.
플레이어가 300 Gold Coins를 구매하고 250 Gold Coins를 소비한 경우에 금화의 보유액이 감소했으므로, 데이터 모델은 Gold Coins를 더 획득할 수 있는 Promo를 표시하기에 적합한 시점이라고 판단할 수 있습니다.
UnityAnalytics.onItemAcquired ("3rd level store", 300.0f, "300goldCoins", 300.0f, "in-game-currency", "3", "ABCD", AcquisitionType.PREMIUM);
UnityAnalytics.onItemSpent ("4th level store", 250.0f, "250goldCoins", 50.0f, "in-game-currency", "4", "EFGH", AcquisitionType.PREMIUM);
플레이어가 100마리의 Cows를 팔아서 400마리의 Pigs를 받았다면 데이터 모델은 줄어든 Cows를 보충할 수 있는 Promo를 표시하기에 적합한 시점이라고 판단할 수 있습니다.
UnityAnalytics.onItemAcquired ("Newbie Bazaar", 400.0f, "400pigs", 400.0f, "in-game-currency", "newbieBazaar", "ABCD", AcquisitionType.SOFT);
UnityAnalytics.onItemSpent ("Newbie Bazaar", 100.0f, "100cows", 0.0f, "in-game-currency", "newbieBazaar", "EFGH", AcquisitionType.SOFT);
플레이어가 게임 내에서 레벨을 통과하지 못했을 때 이 함수를 호출합니다. 데이터 모델은 이를 사용하여 플레이어가 다음 번 플레이할 때 레벨을 통과하는 데 도움이 될 수 있는 제품의 Promo를 표시할 수 있습니다.
public static void onLevelFail (Integer levelIndex);
플레이어가 게임 내에서 레벨을 완료했을 때 이 함수를 호출합니다. onLevelFail
과 함께 사용 시, 사용자가 어느 레벨에서 고전하는지 그리고 각 레벨에서 효과적으로 제공할 수 있는 Promo가 무엇인지를 데이터 모델이 간파할 수 있습니다.
public static void onLevelUp (Integer newLevelIndex);
열거형 자료로 아이템이 SOFT
(게임 내 화폐)인지 아니면 PREMIUM
(현실 세계 화폐)인지를 나타냅니다.
public enum AcquisitionType {
SOFT,
PREMIUM;
public String toString ();
}