在应用程式购买中,只能在编辑器中使用,而不能在Android发布的游戏中

时间:2019-05-23 19:26:21

标签: c# unity3d in-app-purchase in-app-billing

我已经根据官方统一文件在我的游戏中实现了应用购买。在编辑器中,它们工作正常,但在android设备上没有弹出窗口。

我在Logcat中收到此消息

05-24 00:12:27.672 29510-29538/? E/Unity: MissingMethodException: bool UnityEngine.VR.VRSettings.get_enabled()
  at UnityEngine.Purchasing.JSONStore.Purchase (UnityEngine.Purchasing.ProductDefinition product, System.String developerPayload) [0x00129] in <50891d6b80fb4d02b58505065f8b0238>:0 
  at UnityEngine.Purchasing.PurchasingManager.InitiatePurchase (UnityEngine.Purchasing.Product product, System.String developerPayload) [0x0003c] in <e647153c046145fb94ba309b1e626b12>:0 
  at UnityEngine.Purchasing.PurchasingManager.InitiatePurchase (UnityEngine.Purchasing.Product product) [0x00000] in <e647153c046145fb94ba309b1e626b12>:0 
  at UnityInAppsIntegration.BuyProductID (System.String productId) [0x0003e] in <be625aa88f8c4056951a1ebd1cff6864>:0 
  at AnimationManager.Buy (UnityEngine.GameObject pack) [0x00077] in <be625aa88f8c4056951a1ebd1cff6864>:0 
  at UnityEngine.Events.InvokableCall`1[T1].Invoke (T1 args0) [0x00011] in <549ed8055ed14737ac3b841d26182fec>:0 
  at UnityEngine.Events.CachedInvokableCall`1[T].Invoke (System.Object[] args) [0x00001] in <

这是我的购买者

public class UnityInAppsIntegration : MonoBehaviour, IStoreListener{
public static UnityInAppsIntegration THIS;
public static IStoreController m_StoreController;          // The Unity Purchasing system.
private static IExtensionProvider m_StoreExtensionProvider; // The store-specific Purchasing subsystems.


public static string kProductIDConsumable = "consumable";
public static string kProductIDNonConsumable = "nonconsumable";
public static string kProductIDSubscription = "subscription";
private static string pk = "pack1";
private static string pk1 = "pack2";
private static string pk2 = "pack3";
private static string pk3 = "pack4";
// Apple App Store-specific product identifier for the subscription product.
private static string kProductNameAppleSubscription = "com.unity3d.subscription.new";

// Google Play Store-specific product identifier subscription product.
private static string kProductNameGooglePlaySubscription = "com.unity3d.subscription.original";

void Start()
{
    THIS = this;
    // If we haven't set up the Unity Purchasing reference
    if (m_StoreController == null)
    {
        // Begin to configure our connection to Purchasing
        InitializePurchasing();
    }
}

public void InitializePurchasing()
{
    // If we have already connected to Purchasing ...
    if (IsInitialized())
    {
        // ... we are done here.
        return;
    }

    var builder = ConfigurationBuilder.Instance(StandardPurchasingModule.Instance());
    builder.AddProduct(pk, ProductType.Consumable);
    builder.AddProduct(pk1, ProductType.Consumable);
    builder.AddProduct(pk2, ProductType.Consumable);
    builder.AddProduct(pk3, ProductType.Consumable);
    // Add a product to sell / restore by way of its identifier, associating the general identifier
    // with its store-specific identifiers.
    builder.AddProduct(kProductIDConsumable, ProductType.Consumable);
    // Continue adding the non-consumable product.
    builder.AddProduct(kProductIDNonConsumable, ProductType.NonConsumable);
    // And finish adding the subscription product. Notice this uses store-specific IDs, illustrating
    // if the Product ID was configured differently between Apple and Google stores. Also note that
    // one uses the general kProductIDSubscription handle inside the game - the store-specific IDs 
    // must only be referenced here. 
    builder.AddProduct(kProductIDSubscription, ProductType.Subscription, new IDs(){
            { kProductNameAppleSubscription, AppleAppStore.Name },
            { kProductNameGooglePlaySubscription, GooglePlay.Name },
        });

    // Kick off the remainder of the set-up with an asynchrounous call, passing the configuration 
    // and this class' instance. Expect a response either in OnInitialized or OnInitializeFailed.
    UnityPurchasing.Initialize(this, builder);
}


private bool IsInitialized()
{
    // Only say we are initialized if both the Purchasing references are set.
    return m_StoreController != null && m_StoreExtensionProvider != null;
}


public void buypack0()
{
    // buy the consumable product using its general identifier. expect a response either through processpurchase or onpurchasefailed asynchronously.
    BuyProductID(pk);
}
public void buypack1()
{
    // buy the consumable product using its general identifier. expect a response either through processpurchase or onpurchasefailed asynchronously.
    BuyProductID(pk1);
}
public void buypack2()
{
    // buy the consumable product using its general identifier. expect a response either through processpurchase or onpurchasefailed asynchronously.
    BuyProductID(pk2);
}
public void buypack3()
{
    // buy the consumable product using its general identifier. expect a response either through processpurchase or onpurchasefailed asynchronously.
    BuyProductID(pk3);
}
public void BuyNonConsumable()
{
    // Buy the non-consumable product using its general identifier. Expect a response either 
    // through ProcessPurchase or OnPurchaseFailed asynchronously.
    BuyProductID(kProductIDNonConsumable);
}
public void BuySubscription()
{
    // Buy the subscription product using its the general identifier. Expect a response either 
    // through ProcessPurchase or OnPurchaseFailed asynchronously.
    // Notice how we use the general product identifier in spite of this ID being mapped to
    // custom store-specific identifiers above.
    BuyProductID(kProductIDSubscription);
}   public void BuyProductID(string productId)
{
    // If Purchasing has been initialized ...
    if (IsInitialized())
    {
        // ... look up the Product reference with the general product identifier and the Purchasing 
        // system's products collection.
        Product product = m_StoreController.products.WithID(productId);

        // If the look up found a product for this device's store and that product is ready to be sold ... 
        if (product != null && product.availableToPurchase)
        {
            Debug.Log(string.Format("Purchasing product asychronously: '{0}'", product.definition.id));
            // ... buy the product. Expect a response either through ProcessPurchase or OnPurchaseFailed 
            // asynchronously.
            m_StoreController.InitiatePurchase(product);
        }
        // Otherwise ...
        else
        {
            // ... report the product look-up failure situation  
            Debug.Log("BuyProductID: FAIL. Not purchasing product, either is not found or is not available for purchase");
        }
    }
    // Otherwise ...
    else
    {
        // ... report the fact Purchasing has not succeeded initializing yet. Consider waiting longer or 
        // retrying initiailization.
        Debug.Log("BuyProductID FAIL. Not initialized.");
    }
}


// Restore purchases previously made by this customer. Some platforms automatically restore purchases, like Google. 
// Apple currently requires explicit purchase restoration for IAP, conditionally displaying a password prompt.
public void RestorePurchases()
{
    // If Purchasing has not yet been set up ...
    if (!IsInitialized())
    {
        // ... report the situation and stop restoring. Consider either waiting longer, or retrying initialization.
        Debug.Log("RestorePurchases FAIL. Not initialized.");
        return;
    }

    // If we are running on an Apple device ... 
    if (Application.platform == RuntimePlatform.IPhonePlayer ||
        Application.platform == RuntimePlatform.OSXPlayer)
    {
        // ... begin restoring purchases
        Debug.Log("RestorePurchases started ...");

        // Fetch the Apple store-specific subsystem.
        var apple = m_StoreExtensionProvider.GetExtension<IAppleExtensions>();
        // Begin the asynchronous process of restoring purchases. Expect a confirmation response in 
        // the Action<bool> below, and ProcessPurchase if there are previously purchased products to restore.
        apple.RestoreTransactions((result) => {
            // The first phase of restoration. If no more responses are received on ProcessPurchase then 
            // no purchases are available to be restored.
            Debug.Log("RestorePurchases continuing: " + result + ". If no further messages, no purchases available to restore.");
        });
    }
    // Otherwise ...
    else
    {
        // We are not running on an Apple device. No work is necessary to restore purchases.
        Debug.Log("RestorePurchases FAIL. Not supported on this platform. Current = " + Application.platform);
    }
}


//  
// --- IStoreListener
//

public void OnInitialized(IStoreController controller, IExtensionProvider extensions)
{
    // Purchasing has succeeded initializing. Collect our Purchasing references.
    Debug.Log("OnInitialized: PASS");

    // Overall Purchasing system, configured with products for this application.
    m_StoreController = controller;
    // Store specific subsystem, for accessing device-specific store features.
    m_StoreExtensionProvider = extensions;
}


public void OnInitializeFailed(InitializationFailureReason error)
{
    // Purchasing set-up has not succeeded. Check error for reason. Consider sharing this reason with the user.
    Debug.Log("OnInitializeFailed InitializationFailureReason:" + error);
}


public PurchaseProcessingResult ProcessPurchase(PurchaseEventArgs args)
{
    // A consumable product has been purchased by this user.
    if (String.Equals(args.purchasedProduct.definition.id, pk, StringComparison.Ordinal))
    {
        Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
        // The consumable item has been successfully purchased, add 100 coins to the player's in-game score.
        InitScriptName.InitScript.Instance.pack0();
    }
    // Or ... a non-consumable product has been purchased by this user.
    else if (String.Equals(args.purchasedProduct.definition.id, pk1, StringComparison.Ordinal))
    {
        Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
        InitScriptName.InitScript.Instance.pack1();
    }
    // Or ... a subscription product has been purchased by this user.
    else if (String.Equals(args.purchasedProduct.definition.id, pk2, StringComparison.Ordinal))
    {
        Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
        InitScriptName.InitScript.Instance.pack2();
    }
    else if (String.Equals(args.purchasedProduct.definition.id, pk3, StringComparison.Ordinal))
    {
        Debug.Log(string.Format("ProcessPurchase: PASS. Product: '{0}'", args.purchasedProduct.definition.id));
        InitScriptName.InitScript.Instance.pack3();
    }
    // Or ... an unknown product has been purchased by this user. Fill in additional products here....
    else
    {
        Debug.Log(string.Format("ProcessPurchase: FAIL. Unrecognized product: '{0}'", args.purchasedProduct.definition.id));
    }

    // Return a flag indicating whether this product has completely been received, or if the application needs 
    // to be reminded of this purchase at next app launch. Use PurchaseProcessingResult.Pending when still 
    // saving purchased products to the cloud, and when that save is delayed. 
    return PurchaseProcessingResult.Complete;
}



public void OnPurchaseFailed(Product product, PurchaseFailureReason failureReason)
{
    // A product purchase attempt did not succeed. Check failureReason for more detail. Consider sharing 
    // this reason with the user to guide their troubleshooting actions.
    Debug.Log(string.Format("OnPurchaseFailed: FAIL. Product: '{0}', PurchaseFailureReason: {1}", product.definition.storeSpecificId, failureReason));
}}

在游戏机中,我的产品ID是 包0 包1 包2 pack3

期待解决方案,我们将不胜感激。

0 个答案:

没有答案