unity in app purchase (iap)の使い方
TRANSCRIPT
Unity InAppPurchase を組み込んでみよう
Unity In-App Purchase (IAP) とは
• Unity Analytics に付属する機能
• アプリ内課金を簡単に組み込める
• マルチプラットフォーム • Google Play / iOS App Store / Mac
App Store / Windows Store / その他
• コード共通
• ネイティブプラグインを書かなくてOK
IAPをサンプルプロジェクトに組み込んでみよう
• 仕様 • クマは購入したら利用できるようにする • 一度購入したらそれ以降は利用できる(非消費型)
• 購入するまでは利用不可
• コインは購入可能
• 買うとプレイが終わっても存続する(消費型)
• 実装方法 • クマ利用権やコインはPlayerPrefs で記録しておく
Let’s try Unity IAP!
IAPをセットアップする
①In-App Purchase を有効にする②オンにして、Importする③Plugins/UnityPurchasingが
あればOK
購入ボタンと購入APIを紐づける
①Systemを選択→右クリック→
Create Emptyで空オブジェクト。
名前を「IAPManager」に変更
②IAPManager に
Example/Scripts/Workshop/Purchaser.cs
(Example/Scripts/Complete/Purchaser.csではない)
をD&D
③シーンの中で”border_shop”を検索して
アクティブにして見えるようにする
購入ボタンと購入APIを紐づける
④シーンの中で”Item1buy_Button”を検索
Buttonコンポーネントにある
OnClickの+を押して項目追加。
⑤検索ウィンドウの×で検索解除
④で作った項目に①で作った
IAPManager をD&D
⑥No Function をクリックして
Purchase ▶︎ BuyConsumable()
を選択
購入ボタンと購入APIを紐づける
⑦シーンの中で”Item2buy_Button”を検索
Buttonコンポーネントにある
OnClickの+を押して項目追加。
⑧検索ウィンドウの×で検索解除
⑦で作った項目に①で作った
IAPManager をD&D
⑨No Function をクリックして
Purchase ▶︎ BuyNonConsumable()
を選択
購入ボタンと購入APIを紐づける
⑩シーンの中で”border_shop”を検索して
非アクティブに戻す
Purchase.csの購入部分に効果を組み込もう
• Example/Scripts/Workshop/Purchase.cs を開く
• Example/Scripts/CompleteProject/Purchase.csを参考に
• 最初の// TODO:のところに 以下を入れる(コピペ可)
• 次の// TODO: のところに 以下を入れる(コピペ可)
PlayerPrefs.SetInt("CoinNum", PlayerPrefs.GetInt("CoinNum") + 100); GameObject.Find(“CoinNumUI"). GetComponent<ScoreManager>().UpdateCoin();
PlayerPrefs.SetInt("NewCharaUnlocked", 1);
CharaSelector.csに効果を反映させよう
• 購入したキャラを利用可能・不可を設定する
• Example/Scripts/Workshop/CharaSelector.cs を開く
• Example/Scripts/CompleteProject/CharaSelector.csを参考に
• 最初の// TODO:のところに 以下を入れる(コピペ可) if (PlayerPrefs.GetInt("NewCharaUnlocked") == 0) { newOneButton.interactable = false; } else{ newOneButton.interactable = true; }
Unity IAPの課金プロセスを紐解く
課金部分Purchase.cs を紐解く
• InitializePurchasing • Awakeで自動で行われ、各ストアでの商品IDと共通商品IDを紐付けを行っている。
• ストアが違ってもゲーム内商品が同じであれば、同じIDの方が混乱がなくていい。
• BuyConsumable、BuyNonConsumable、BuySubscription • ストア別に購入アイテムを別にしたりしていないことに注目
• BuyProductID • try~catch で購入シーケンスでの例外をキャッチ
• m_StoreController.InitiatePurchase で、デバイスの購入ダイアログに飛ぶ
課金部分Purchase.cs を紐解く
• RestorePurchases • アプリを再インストールした際に、昔買った商品をリストアする処理
• AppStore は明示的にアプリ側で復活させる必要がある
• OnInitialized • 初期化がうまくいけば勝手に呼び出される関数
• 全体の購入システム(m_StoreController) と、ストア特有のサブシステム(m_StoreExtensionProvider) のインスタンス化
• ProcessPurchase • ストアで課金が完了した段階で、課金によるゲームへの効果を処理するところ
AppStore の課金アイテムを 実際に追加してみよう
AppStore に課金アイテムを登録
①iTunes Connect へ行って
新しいAppを作る②Bundle IDはCloud Buildの
�際に、作ったものを代入。
�その他の項目は適当に
③今作った新しいアプリを選択し、
機能→App 内課金→+を選択。
AppStore に課金アイテムを登録
④消費型を選択 ⑤参照名は公開されないので適当に
�製品IDは逆ドメイン名でユニークID。
�(例:com.warapuri.unitychanrollball.coin100)
⑥ 価格も設定
com.warapuri.unitychanrollball.coin100
AppStore に課金アイテムを登録
⑧スクリーンショットを選択。
�配布USBに「Shop.png」が
�あるので、利用してください
⑦言語を追加を設定。課金ポップアップで
�表示される内容なので、慎重に。
⑨Saveを押して保存すると、
�登録される
Sandboxで試してみる
①ユーザーと役割→Sandboxテスター
�→テスター+ボタンでテスターを追加
②テスターとして登録
�という感じで「+」を使うと無駄に
�メールアカウント作らなくて便利
③テストするiOS端末で
�設定→iTunes & App Store
�→Apple IDを選択し、
�一旦サインアウトする
Sandboxで試してみる
⑤アプリを立ち上げて、
�iOS端末で購入しようとすると、
�[Environment: Sandbox]
�と表示されていれば成功
④Purchase.cs の kProductNameAppleConsumable の文字列部分を
�先ほどの製品IDに変更する
“com.warapuri.unitychanrollball.coin100”;
Google Play の課金アイテムを 実際に追加してみよう
②タイトルを適当に入れて
�APKをアップロードを選択
①Google Play で
���アイコン→
�新しいアプリを追加
③アルファ版テストを選択
�APKファイルをアップロードを選択
�(Cloud Buildの際に作ったAPK)
Google Play で新しいアプリを登録 APK
④「クローズドアルファテスト」を
�選択
⑤Create List でテスターリストの作成
�リスト名は適当に。
�メールアドレスは自分の
�Google アカウントを入れてください
⑥作ったテスターリストに
�有効に✔を入れる
Google Play で新しいアプリを登録 APK
Google Play で新しいアプリを登録 ストアの掲載情報
②簡単な説明と詳細な説明をそこそこちゃんと記載する。
�(適当に書いたらなりすましに誤認されました)
①ストアの掲載情報を選択
③配布したUSBの中に「IAP」フォルダの中に画像を利用
�スナップショットに2枚以上、
�高解像度アイコン、宣伝用画像をそれぞれ上記のようにD&D
�アップロード
④アプリのタイプをゲーム。
�カテゴリをアーケード。
�コンテンツレーティングを全ユーザー対象
�プライバシーポリシーは「今回は〜」に✔
Google Play で新しいアプリを登録 ストアの掲載情報
Google Play で新しいアプリを登録 コンテンツのレーティング
①コンテンツのレーティングを選択 ②画面に従ってレーティングを設定
Google Play で新しいアプリを登録 価格と販売/配布地域
①価格と販売/配布地域を選択 ②アプリの価格は無料。
�全ての国を選択。
�
③同意事項に全て✔
�一番上の「ドラフトを保存」をクリック
Google Play で新しいアプリを登録 アプリ内アイテム
①アプリ内アイテムを選択
�+新しいアイテムを追加を選択
②管理対象のアイテムを選択
�アイテムIDには逆ドメイン
�(アイテムIDは後ほど使うので忘れずに)
�次へを選択�
③タイトル、説明は公開される情報なので
�ちゃんと記入。
�デフォルトの価格を記入後、価格を
�自動換算ボタンで各国の値段を算出。
�最後に右上の「無効」を「有効」に
com.warapuri.unitychanrollball.coin100
⑤アプリを立ち上げて、
�Android端末で購入しようとすると、
�「これはテスト用の注文です」
�と表示されていれば成功
④Purchase.cs の kProductNameGooglePlayConsumable の文字列部分を
�先ほどのアイテムIDに変更する
Google Play で新しいアプリを登録 アプリ内アイテム
“com.warapuri.unitychanrollball.coin100”;
右のようなエラーが出ている場合の考えられる原因 1) アイテム内アイテムを「有効」にしていない
2) アイテムIDが違う
3) テスターとGoogle Playアカウントが違う
対処法:設定→アプリ→Google Playストア→ストレージ→データ消去
4) 反映されるまで時間がまだ立っていない
トラブルシューティング
それでもエラーが治らない場合 1) アプリのステータスが「公開中」まで待つ
2) USBからインストールではなく、APKアップロード→Google Playからダウンロードで試してみる
3) Androidデバイスを再起動してみる
4) 一回寝て、翌日もう一回チャレンジする
トラブルシューティング
注意
• PlayerPrefsで商品の反映をさせていたが、本来はNG • 簡単に改造されてしまう
• サーバー側で管理しローカル側では一切情報を保持しない
IAP、もう少し深く。
レシート検証
• http://docs.unity3d.com/ja/current/Manual/UnityIAPValidatingReceipts.html
• 購入時にストアからくるレシートデータをローカルで確認する • Google Play 公開キー(要設定)
• Apple のルート証明書(自動設定)
• 購入後のシーケンスなので、アプリケーション側でUIでユーザーに知らせる必要がある
レシート検証
①Window→Unity IAP→
�Receipt Validation Obfuscatorを
�選択して、「IAP Obfuscator」を
�表示
②Google Play Developer Consoleで
�サービスとAPIを選択し、
�「このアプリのライセンス キー」の
�部分を丸々コピーする
③「IAP Obfuscator」の項目に
�ペーストして、Generate IAP〜を
�クリックして、コード生成する。
レシート検証public PurchaseProcessingResult ProcessPurchase (PurchaseEventArgs e){ // Unity IAP's validation logic is only included on these platforms.#if UNITY_ANDROID || UNITY_IOS || UNITY_STANDALONE_OSX // Prepare the validator with the secrets we prepared in the Editor // obfuscation window. var validator = new CrossPlatformValidator(GooglePlayTangle.Data(), AppleTangle.Data(), Application.bundleIdentifier);
try { // On Google Play, result will have a single product Id. // On Apple stores receipts contain multiple products. var result = validator.Validate(e.purchasedProduct.receipt); Debug.Log("Receipt is valid. Contents:"); foreach (IPurchaseReceipt productReceipt in result) { Debug.Log(productReceipt.productID); Debug.Log(productReceipt.purchaseDate); Debug.Log(productReceipt.transactionID); } // Unlock the appropriate content here. } catch (IAPSecurityException) { Debug.Log("Invalid receipt, not unlocking content"); }#endif
return PurchaseProcessingResult.Complete;}
マルチプラットフォーム用確認クラス
レシート確認
問題なければ、ここで購入したことに問題があればここで、買えないことをユーザーに知らせる必要がある