Unity IAP | In App Purchase | Unknown Error - android

I want to implement IAP in my android game.
This is my code, it is from the official unity website:
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Purchasing;
using UnityEngine.UI;
public class Purchaser : MonoBehaviour, IStoreListener {
private static IStoreController m_StoreController; // The Unity Purchasing system.
private static IExtensionProvider m_StoreExtensionProvider; // The store-specific Purchasing subsystems.
public Text text;
public static string kProductIDConsumable = "pile_shadycoin";
void Start() {
if (m_StoreController == null) {
InitializePurchasing();
}
}
public void InitializePurchasing() {
if (IsInitialized()) {
return;
}
var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
builder.AddProduct(kProductIDConsumable, ProductType.Consumable);
UnityPurchasing.Initialize(this, builder);
}
private bool IsInitialized() {
return m_StoreController != null && m_StoreExtensionProvider != null;
}
public void BuyConsumable() {
BuyProductID(kProductIDConsumable);
}
void BuyProductID(string productId) {
if (IsInitialized()) {
Product product = m_StoreController.products.WithID(productId);
if (product != null && product.availableToPurchase) {
text.text = "Purchasing product asychronously: '{0}'";
m_StoreController.InitiatePurchase(product);
} else {
text.text = "BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase";
}
} else {
text.text = "BuyProductID FAIL. Not initialized.";
}
}
public void OnInitialized(IStoreController controller, IExtensionProvider extensions) {
text.text = "OnInitialized: PASS";
m_StoreController = controller;
m_StoreExtensionProvider = extensions;
}
public void OnInitializeFailed(InitializationFailureReason error) {
text.text = "OnInitializeFailed InitializationFailureReason:" + error;
}
public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args) {
if (String.Equals(args.purchasedProduct.definition.id, kProductIDConsumable, StringComparison.Ordinal)) {
text.text = "ProcessPurchase: PASS. Product: '{0}'";
} else {
text.text = "ProcessPurchase: FAIL. Unrecognized product: '{0}'";
}
return PurchaseProcessingResult.Complete;
}
public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason) {
text.text = failureReason + "";
}
}
I am using the consumable item pile_shadycoin.
In the picture you can see the id and that it's active (it's german)
Picture of Google Play
If I build my project and put it on my smartphone and press the button, which is linked to BuyConsumable() it opens the menu and says:
Fehler Der angeforderte Artikel kann nicht gekauft werden
In English:
Error The requested item cannot be purchased

I found my error. I didn't released the build on alpha or beta.
I pulled the APK directly to my phone.

Related

Unity, Facebook SDK, in Android build the app crashes

I am integrating Unity Facebook SDK to a project, right now I am making a log-in system. I have written a script, attached it to an object on a scene, created a button, added the FbLogin method as a listener of OnClick UnityEvent of my button and built an app for Android. Also I have pasted all the needed keys and tokens.
using System.Collections.Generic;
using UnityEngine;
using Facebook.Unity;
class FacebookLoginSystem
{
private void Awake()
{
FB.Init(SetInit, OnHideUnity);
}
void SetInit()
{
if (FB.IsLoggedIn)
{
Debug.Log("Logged in Successfuly!");
}
else
{
Debug.Log("FB is not loggid in");
}
}
void OnHideUnity(bool isGameShown)
{
if (isGameShown)
{
Time.timeScale = 1;
}
else
{
Time.timeScale = 0;
}
}
public void FbLogin()
{
List<string> permessions = new List<string>();
permessions.Add("public_profile");
FB.LogInWithReadPermissions(permessions, AuthCallResult);
}
private void AuthCallResult(ILoginResult result)
{
if (result.Error != null)
{
Debug.Log(result.Error);
}
else
{
if (FB.IsLoggedIn)
{
Debug.Log("FB logged in");
Debug.Log(result.RawResult);
FB.API("/me?fields=first_name", HttpMethod.GET, callbackData);
}
else
{
Debug.Log("Login Failed!");
}
}
}
}
But when I press the button in my build, I get this. ("Something went wrong, we are working on it...")
Tell me, please, why does it happen?
This happens when I press the button
UPD:
I have replaced the methods FbLogin and AuthCallback with these versions. Also I added a serialized field TextForLogging to see my logs in Build, and it tells me that "User cancelled login".
public void FbLogin()
{
var perms = new List<string>() { "public_profile", "email" };
FB.LogInWithReadPermissions(perms, AuthCallback);
}
private void AuthCallback(ILoginResult result)
{
if (FB.IsLoggedIn)
{
// AccessToken class will have session details
var aToken = Facebook.Unity.AccessToken.CurrentAccessToken;
// Print current access token's User ID
Debug.Log(aToken.UserId);
TextForLogging.text += $"\n{aToken.UserId}";
// Print current access token's granted permissions
foreach (string perm in aToken.Permissions)
{
Debug.Log(perm);
TextForLogging.text += $"\n{perm}";
}
FB.API("/me?fields=first_name", HttpMethod.GET, callbackData);
}
else
{
Debug.Log("User cancelled login");
TextForLogging.text += "\nUser cancelled login";
}
}

Does Google Play Services in Unity, store data somewhere inside Unity?

I need help with Google Play Games plugin in unity.
My game have some scenes (1 - menu, 5 - game scenes). I downloaded plugin and write code, that initializing play games and sign user in. After this, I'm using firebase initialization and login with Play Games.
Everything works fine, when I'm starting my game (I checked logs with logcat and it shows my login and message that sign in was successful both for firebase and play games services). My script that controls firebase and google play service contains DontDestroyOnLoad and it Destroys duplicates.
When I'm returning from game scene to menu again, logcat saying that that was error and it can't login. I can press log out (on button) and log in again, and it will be good.
So, can someone answer me question, should my PlayServices walk to other scenes with DontDestroyOnLoad, or it stores data somewhere in Unity libraries (SocialPlatform)? I can't submit achievements on game scene and I can't doing other things with this...
Thanks
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using GooglePlayGames;
using GooglePlayGames.BasicApi;
using Firebase;
using Firebase.Auth;
using Firebase.Analytics;
using UnityEngine.SocialPlatforms;
using UnityEngine.SceneManagement;
using TMPro;
public class GooglePlayServices : MonoBehaviour
{
private GPG_CloudSaveSystem cloudSaveSystem = new GPG_CloudSaveSystem();
private string authCode;
private bool firebaseInitialized;
DependencyStatus dependencyStatus = DependencyStatus.UnavailableOther;
public static GooglePlayServices instance;
private bool isFirebaseLogged, isPlayGamesLogged;
FirebaseAuth auth;
FirebaseUser user;
private string userNametest, userNameId;
void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(this.gameObject);
}
else
{
DestroyImmediate(gameObject);
}
auth = FirebaseAuth.DefaultInstance;
PlayGamesClientConfiguration config = new
PlayGamesClientConfiguration.Builder()
.EnableSavedGames()
.RequestServerAuthCode(false)
.Build();
// Enable debugging output (recommended)
PlayGamesPlatform.DebugLogEnabled = true;
// Initialize and activate the platform
PlayGamesPlatform.InitializeInstance(config);
PlayGamesPlatform.Activate();
if (!isPlayGamesLogged)
{
PlayGamesPlatform.Instance.Authenticate(SignInCallback, false);
}
}
private void Start()
{
Debug.Log("User name: " + userNametest + " | User ID: " + userNameId);
}
void LoginFirebase()
{
if (Social.localUser.authenticated)
{
authCode = PlayGamesPlatform.Instance.GetServerAuthCode();
}
else
{
PlayGamesPlatform.Instance.Authenticate(SignInCallback, false);
authCode = PlayGamesPlatform.Instance.GetServerAuthCode();
}
//FirebaseAuth auth = FirebaseAuth.DefaultInstance;
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
// Set the user's sign up method.
FirebaseAnalytics.SetUserProperty(
FirebaseAnalytics.UserPropertySignUpMethod,
"PlayGames");
Credential credential = PlayGamesAuthProvider.GetCredential(authCode);
auth.SignInWithCredentialAsync(credential).ContinueWith(task =>
{
if (task.IsCanceled)
{
Debug.LogError("SignInWithCredentialAsync was canceled.");
return;
}
if (task.IsFaulted)
{
Debug.LogError("SignInWithCredentialAsync encountered an error: " + task.Exception);
return;
}
FirebaseUser newUser = task.Result;
userNametest = newUser.DisplayName;
userNameId = newUser.UserId;
Debug.LogFormat("User signed in successfully: {0} ({1})",
newUser.DisplayName, newUser.UserId);
// Set the user ID.
FirebaseAnalytics.SetUserId(newUser.UserId);
isFirebaseLogged = true;
});
// Set default session duration values.
FirebaseAnalytics.SetMinimumSessionDuration(new TimeSpan(0, 0, 10));
FirebaseAnalytics.SetSessionTimeoutDuration(new TimeSpan(0, 30, 0));
firebaseInitialized = true;
}
public void EventLevelFinished(int levelNumber)
{
string eventLog = "Level_finished_" + (levelNumber + 1).ToString();
switch (levelNumber)
{
case 2:
{
FirebaseAnalytics.LogEvent(eventLog);
break;
}
case 9:
{
FirebaseAnalytics.LogEvent(eventLog);
break;
}
case 19:
{
FirebaseAnalytics.LogEvent(eventLog);
break;
}
case 29:
{
FirebaseAnalytics.LogEvent(eventLog);
break;
}
case 39:
{
FirebaseAnalytics.LogEvent(eventLog);
break;
}
case 49:
{
FirebaseAnalytics.LogEvent(eventLog);
break;
}
case 59:
{
FirebaseAnalytics.LogEvent(eventLog);
break;
}
}
}
public void EventLogCustomEvent(string log)
{
FirebaseAnalytics.LogEvent(log);
}
public string GetFirebaseUser()
{
return user.DisplayName + " | " + user.UserId;
}
public void SaveToCloud()
{
JsonToCloud.instance.BuildSaveString();
cloudSaveSystem.saveString = Prefs.CloudSaveString;
cloudSaveSystem.SaveToCloud();
}
public void LoadFromCloud()
{
cloudSaveSystem.LoadFromCloud();
Prefs.CloudSaveString = cloudSaveSystem.saveString;
JsonToCloud.instance.StringToData();
SceneManager.LoadScene(SceneManager.GetActiveScene().name);
}
public void ShowSavedGames()
{
cloudSaveSystem.showUI();
}
public void AnalyticsLogin()
{
FirebaseAnalytics.LogEvent(FirebaseAnalytics.EventLogin);
}
public void AnalyticsProgress()
{
FirebaseAnalytics.LogEvent("progress", "percent", 0.4f);
}
void InitializeFirebase()
{
FirebaseAnalytics.SetAnalyticsCollectionEnabled(true);
// Set the user's sign up method.
FirebaseAnalytics.SetUserProperty(
FirebaseAnalytics.UserPropertySignUpMethod,
"PlayGames");
// Set the user ID.
FirebaseAnalytics.SetUserId("uber_user_510");
// Set default session duration values.
FirebaseAnalytics.SetMinimumSessionDuration(new TimeSpan(0, 0, 10));
FirebaseAnalytics.SetSessionTimeoutDuration(new TimeSpan(0, 30, 0));
firebaseInitialized = true;
}
public void ShowAchievements()
{
if (PlayGamesPlatform.Instance.localUser.authenticated)
{
PlayGamesPlatform.Instance.ShowAchievementsUI();
}
else
{
Debug.Log("Cannot show Achievements, not logged in");
}
}
public void SignIn()
{
if (!PlayGamesPlatform.Instance.localUser.authenticated)
{
// Sign in with Play Game Services, showing the consent dialog
// by setting the second parameter to isSilent=false.
PlayGamesPlatform.Instance.Authenticate(SignInCallback, false);
}
else
{
// Sign out of play games
PlayGamesPlatform.Instance.SignOut();
}
AnalyticsLogin();
}
public void SignInCallback(bool success)
{
if (success)
{
isPlayGamesLogged = true;
Debug.Log("(Lollygagger) Signed in!");
authCode = PlayGamesPlatform.Instance.GetServerAuthCode();
////////////////////////////////
FirebaseApp.CheckAndFixDependenciesAsync().ContinueWith(task =>
{
dependencyStatus = task.Result;
if (dependencyStatus == DependencyStatus.Available)
{
if (!isFirebaseLogged)
{
LoginFirebase();
}
}
else
{
Debug.LogError(
"Could not resolve all Firebase dependencies: " + dependencyStatus);
}
});
/////////////////////////////////////////
}
else
{
Debug.Log("(Lollygagger) Sign-in failed...");
}
}
}
One guy on github issues answered me, that there is no need to use DontDestroyOnLoad, just use once at main scene and that's all

Unity - Photon OnJoinedRoom not being called

I am using photon to make a FPS game for android.
Here is the code:
using UnityEngine;
using UnityEngine.UI;
public class SceneLoaderButton : Photon.PunBehaviour {
public string roomName, mapNameGL, password;
public GameObject loadingPan;
public MenuRooms menuManager;
// Use this for initialization
void Start () {
Button btn = GetComponent<Button> ();
btn.onClick.AddListener (ConnectCustomRoom);
}
// Update is called once per frame
void Update () {
}
void ConnectCustomRoom(){
string room = roomName;
RoomInfo[] ri;
ri = PhotonNetwork.GetRoomList ();
bool correct = false;
string passwd, mapName = "";
passwd = password;
foreach (RoomInfo info in ri) {
if (info.name == room) {
if (info.customProperties ["Password"].ToString() == passwd) {
print(info.playerCount + "/" + info.maxPlayers);
if (info.playerCount < info.maxPlayers)
{
correct = true;
}
else
{
menuManager.error("No room for you");
}
mapName = info.customProperties ["MapName"].ToString ();
}
else
{
menuManager.error("Incorrect password");
}
}
}
mapNameGL = mapName;
print(mapNameGL);
if (correct) {
print("Correct");
loadingPan.active = !loadingPan.active;
PhotonNetwork.playerName = "Player" + UnityEngine.Random.Range (1000,9999).ToString();
PhotonNetwork.JoinRoom(room);
}
}
void OnJoinedRoom()
{
print("Joined room: " + roomName);
//We joined room, load respective map
Application.LoadLevel(mapNameGL);
}
}
This is the code from button. It is instantiated and it should join the room, then load the scene. In other scripts, "onjoinedroom" callback works, even if I inherite from Photon.MonoBehaveiour, not from PUNBehaveiour. What is wrong?
based on PUN documentation, it is a virtual member, so you can override that method.
try to change the method to :
override void OnJoinedRoom ()
{
//your codes
}
//or
public override void OnJoinedRoom ()
{
//your codes
}
This class provides a .photonView and all callbacks/events that PUN
can call. Override the events/methods you want to use. By extending
this class, you can implement individual methods as override.
Hope that's help you.
Reference :
PUN Documentation

Unity: Admob Reward Video Ad Doesn't Call Events

I'm trying to add an Admob reward video ad to my android game made in Unity. The displays fine but when I close the ad, the reward is never given. I've tested the code in the function and the works fine so I think the problem is that is isn't gettting called. Can anyone help me?
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System;
using GoogleMobileAds;
using GoogleMobileAds.Api;
public class textEdit : MonoBehaviour
{
public Image lifeAdUI;
static Image lifeAdUIStat;
public Text adFailUI;
static Text adFailUIStat;
public Button lifeButton;
private static RewardBasedVideoAd videoAd;
static bool adTime = false;
static bool adPlaying = false;
static int pass = 0;
bool watched;
// Use this for initialisation
void Start()
{
Button btn = lifeButton.GetComponent<Button>();
btn.onClick.AddListener(VideoAd);
videoAd = RewardBasedVideoAd.Instance;
videoAd.OnAdFailedToLoad += HandleOnAdFailedToLoad;
videoAd.OnAdOpening += HandleOnAdOpening;
videoAd.OnAdClosed += HandleOnAdClosed;
videoAd.OnAdRewarded += HandleOnAdReward;
videoAd.OnAdLeavingApplication += HandleOnAdLeavingApplication;
videoAd.OnAdLoaded += HandleOnAdLoaded;
videoAd.OnAdStarted += HandleOnAdStarted;
lifeAdUIStat = lifeAdUI;
adFailUIStat = adFailUI;
}
public static void LoadVideoAd()
{
#if UNITY_EDITOR
string adUnitID = "unused";
#elif UNITY_ANDROID
string adUnitID = "ca-app-pub-3025391748532285/9122766975";
#elif UNITY_IPHONE
string adUnitID = "";
#else
string adUnitID = "unexpected_platform";
#endif
videoAd.LoadAd(new AdRequest.Builder().Build(), adUnitID);
pass = pass + 1;
}
void VideoAd()
{
if (videoAd.IsLoaded())
{
videoAd.Show();
}
else
{
//ad not loaded
}
}
//Ad Events
public void HandleOnAdFailedToLoad(object sender, AdFailedToLoadEventArgs args)
{
if (pass < 2)
{
LoadVideoAd();
}
else
{
StartCoroutine(adFailCoro());
}
}
public void HandleOnAdOpening(object ssender, EventArgs args)
{
adPlaying = true;
}
public void HandleOnAdClosed(object sender, EventArgs args)
{
adPlaying = false;
watched = true;
if (watched == true)
{
control controlScript = GameObject.FindGameObjectWithTag("Control").GetComponent<control>();
lifeAdUI.enabled = false;
StartCoroutine(controlScript.ExtraLife());
}
}
public void HandleOnAdReward(object sender, EventArgs args)
{
watched = true;
}
public void HandleOnAdLeavingApplication(object sender, EventArgs args)
{
}
public void HandleOnAdLoaded(object sender, EventArgs args)
{
}
public void HandleOnAdStarted(object sender, EventArgs args)
{
}
}
If you called VideoAd to show your video Ad but due to some unforeseen reason your video is not loaded yet, or having loading failure, so request to load your Ad Again.
void VideoAd()
{
if (videoAd.IsLoaded())
{
videoAd.Show();
}
else
{
LoadVideoAd();
}
}
Request to load new Video Ad when your Ad is closed by user.
public void HandleOnAdClosed(object sender, EventArgs args)
{
adPlaying = false;
watched = true;
if (watched == true) //what is the need of this condition, it always true
{
control controlScript = GameObject.FindGameObjectWithTag("Control").GetComponent<control>();
lifeAdUI.enabled = false;
StartCoroutine(controlScript.ExtraLife());
LoadVideoAd();
}
}
Init Admob Unity Plugin
using admob;
Admob.Instance().initAdmob("admob banner id", "admob interstitial id");//admob id with format ca-app-pub-279xxxxxxxx/xxxxxxxx
//Admob.Instance().initAdmob("ca-app-pub-3940256099942544/2934735716", "ca-app-pub-3940256099942544/4411468910");
Here is the minimal code to create an admob video.
Admob.Instance().loadRewardedVideo("ca-app-pub-3940256099942544/1712485313");
Video need to be explicitly shown at an appropriate stopping point in your app, check that the video is ready before showing it:
if (Admob.Instance().isRewardedVideoReady()) {
Admob.Instance().showRewardedVideo();
}
handle reward
Admob.Instance().videoEventHandler += onVideoEvent;
void onVideoEvent(string eventName, string msg)
{
Debug.Log("handler onAdmobEvent---" + eventName + " " + msg);
if (eventName == AdmobEvent.onRewarded)
{
//msg is the reward count.you can handle it now
}
}
ref admob plugin

trouble integrating facebook into a unity android project

I've been trying to integrate facebook into my project and I've successfully managed to do just that with the help of some online tutorials however I do have one persisting problem...
The code is set to pause the game using
Time.timescale = 0; when a facebook window is up and to resume play using Time.timescale = 1; when it's not
but that just doesn't happen, and the function that pauses the game never gets called...
Here's the code :
using UnityEngine;
using UnityEngine.UI;
using System.Collections;
using System.Collections.Generic;
public class FBHolder : MonoBehaviour {
public GameObject UIFBIsLoggedIn;
public GameObject UIFBNotLoggedIn;
public GameObject UIFBAvatar;
public GameObject UIFBUserName;
public GameObject ScoreEntryPanel;
public GameObject ScoreScrollList;
private List<object> scoreslist = null;
private Dictionary<string, string> profile = null;
void Awake()
{
FB.Init (SetInit, onHideUnity);
}
private void SetInit()
{
Debug.Log ("FB Init Done");
if(FB.IsLoggedIn)
{
Debug.Log ("FB Logged In");
managefbmenus(true);
}
else
{
managefbmenus(false);
}
}
private void onHideUnity(bool isGameShown)
{
if(!isGameShown)
{
Debug.Log ("Pause Game");
Time.timeScale = 0;
}
else
{
Time.timeScale = 1;
}
}
public void FBLogin()
{
FB.Login ("email,publish_actions", Authcallback);
}
void Authcallback(FBResult result)
{
if(FB.IsLoggedIn)
{
Debug.Log ("FB Login Worked");
managefbmenus(true);
}
else
{
Debug.Log ("FB Login Failed");
managefbmenus(false);
}
}
void managefbmenus(bool isLoggedIn)
{
if(isLoggedIn)
{
UIFBIsLoggedIn.SetActive(true);
UIFBNotLoggedIn.SetActive(false);
SetScore();
//Get profile picture
FB.API(Util.GetPictureURL("me", 128, 128), Facebook.HttpMethod.GET, DealWithProfilePicture);
FB.API("/me?fields=id,first_name", Facebook.HttpMethod.GET,DealwithUserName);
//Get username
}
if(!isLoggedIn)
{
UIFBIsLoggedIn.SetActive(false);
UIFBNotLoggedIn.SetActive(true);
}
}
void DealWithProfilePicture(FBResult result)
{
if(result.Error != null)
{
Debug.Log ("Problem getting profile picture");
FB.API(Util.GetPictureURL("me", 128, 128), Facebook.HttpMethod.GET, DealWithProfilePicture);
return;
}
Image UserAvatar = UIFBAvatar.GetComponent<Image> ();
UserAvatar.sprite = Sprite.Create (result.Texture, new Rect(0, 0, 128, 128), new Vector2(0, 0));
}
void DealwithUserName(FBResult result)
{
if(result.Error != null)
{
Debug.Log ("Problem getting username");
FB.API("/me?fields=id,first_name", Facebook.HttpMethod.GET,DealwithUserName);
return;
}
profile = Util.DeserializeJSONProfile(result.Text);
Text UserMsg = UIFBUserName.GetComponent<Text>();
UserMsg.text = "Hello, " + profile ["first_name"];
}
Any ideas on what could be causing this issue?
BTW: I'm using unity 5.
I guess you don't need to pause your game while Facebook UI is displayed. you can just call it as:
FB.Init(SetInit);

Categories

Resources